Подтвердить что ты не робот

AngularJs Передача сложных данных в директиву

У меня есть следующая директива:

<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) {
        }
    };
});

Спасибо

4b9b3361

Ответ 1

Читайте на Официальный сайт Angularjs:

@или @attr - привязать свойство локальной области к значению DOM атрибут. Результат всегда является строкой, поскольку атрибуты DOM строки. Если имя attr не указано, то имя атрибута предполагается, что оно совпадает с локальным именем. Определенное и видимое определение области: {localName: '@myAttr'}, то свойство widget scope localName будет отображать интерполированные значение приветствия {{name}}. Поскольку атрибут name изменяется так же, как и localName в области виджетов. Имя читается из родительская область (не область компонента).

Таким образом, вы можете отправить только строку, чтобы передать объект, вам нужно настроить двунаправленную привязку с помощью =.

   scope: {
        details: '=',
    },

И ваш HTML будет выглядеть как

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

Ответ 2

Кто-то спросил, как это сделать, не выделяя область действия, вот решение:

<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);
            }
        }
    };
});

Мы можем даже использовать $интерполяцию, если любые значения в attrs.details должны быть динамически заданы с помощью выражений angular {{...}}...

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

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

Важное примечание: Я не тестировал этот метод с помощью angular 2.