AngularJs Передача складних даних директиві


76

У мене є така директива:

<div teamspeak details="{{data.details}}"></div>

це структура об’єкта:

data: {
                details: {
                    serverName: { type: 'text', value: 'my server name' },
                    port: { type: 'number', value: 'my port' },
                    nickname: { type: 'text' },
                    password: { type: 'password' },
                    channel: { type: 'text' },
                    channelPassword: { type: 'password' },
                    autoBookmarkAdd: { type: 'checkbox' }
                }
}

і я хочу, щоб він генерував посилання на основі даних всередині data.detailsоб’єкта. На жаль, це не працює, оскільки я якось не можу отримати доступ до внутрішніх значень detailsоб'єкта , але якщо я передаю йому просту структуру даних, наприклад:

<div teamspeak details="{{data.details.serverName.value}}"></div>

Я можу отримати до нього доступ за допомогою {{details}}.

Ось мій Директивний Кодекс:

App.directive('teamspeak', function () {
    return {
        restrict: 'A',
        template: "<a href='ts3server://{{details.serverName.value}}:{{details.port.value}}'>Teamspeak Server</a>",
        scope: {
            details: '@details',
        },
        link: function (scope, element, attrs) {
        }
    };
});

Дякую

Відповіді:


106

Прочитайте на офіційному сайті Angularjs пояснення:

@ або @attr - прив'язує властивість локальної області до значення атрибута DOM. Результатом завжди є рядок, оскільки атрибути DOM є рядками. Якщо ім'я attr не вказано, тоді ім'я атрибута вважається таким самим, як і місцеве ім'я. Дане та визначення віджета обсягу: {localName: '@ myAttr'}, тоді властивість сфери віджета localName відображатиме інтерпольоване значення hello {{name}}. Зі зміною атрибута name змінюється і властивість localName у області віджета. Ім'я зчитується з батьківської області (не сфери дії компонента).

Таким чином, ви можете надіслати лише рядок, щоб передати об'єкт, вам потрібно налаштувати двонаправлене прив'язку за допомогою =.

   scope: {
        details: '=',
    },

І ваш HTML-код буде виглядати так

<div teamspeak details="data.details"></div>

2
Здається, це не працює з TypeScript. Що я зробив, це створив інтерфейс, який визначає область дії. У цьому інтерфейсі у мене є власний об'єкт. При присвоєнні інтерфейсу області дії я не можу цього зробити object = '=', оскільки ви не можете призначити рядок об’єкту типу ObjectType. Будь-які пропозиції щодо того, як це зробити за допомогою TypeScript?
bilo-io

це також можна зробити за допомогою прив'язок: {} я опублікую відповідь, як тільки зроблю це для роботи :)
Sonic Soul

39

Хтось запитав про те, як це зробити, не ізолюючи область дії, ось рішення:

<div teamspeak details="{{data.details}}"></div>

App.directive('teamspeak', function () {
    return {
        restrict: 'A',
        template: "<a href='ts3server://{{details.serverName.value}}:{{details.port.value}}'>Teamspeak Server</a>",
        link: function (scope, element, attrs) {
            if(attrs.details){
                scope.details = scope.$eval(attrs.details);
            }
        }
    };
});

Ми навіть можемо використовувати, $interpolateякщо будь-які значення в attrs.detailsповинні бути динамічно встановлені з кутовими виразами {{...}} ...

scope.details = scope.$eval($interpolate(attrs.details)(scope));

(не забудьте ввести $interpolateслужбу у свою директиву)

Важлива примітка: Я не тестував цей метод з кутовим 2.


1
Якщо ви використовуєте attrs, вам буде важко перетворити цю директиву на angular 2. Це лише особиста підказка.
Пітер Хуанг

спасибі @ sh977218, я додав примітку, що цей метод не тестується з кутовим 2
plong0
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.