Я пытаюсь иметь двустороннюю привязку к директиве.
Я не могу использовать scope
директивы (несколько директив по элементу), поэтому мне придется делать это в функции compile(){...}
Это упрощенная версия этой директивы:
.directive('myDialog', function() {
return {
restrict: 'E',
templateUrl: 'my-dialog.html',
compile: function(tElement, tAttrs, transclude) {
return function($scope, $element, $attributes) {
$scope.label = $scope.$eval($attributes.label);
// when I set the label on something this should update the parent
$scope.label = "test";
}
}
};
Итак, как я могу это сделать, когда я изменяю lable в моей директиве, он обновляет значение в главном приложении, а наоборот
Plunker для тестирования: http://plnkr.co/edit/lARCrGD5FsnOWQZrahIl?p=preview
UPDATE: вот фактическая установка со всей логикой для того, что я пытаюсь архивировать: http://codepen.io/cskiwi/pen/eJryqK?editors=1010
В строке 101 я хочу установить тестирование var на true, позже я также собираюсь установить тестирование var на false вне этой директивы
UPDATE2: Получил что-то, это может быть что-то посмотреть в:
return {
restrict: "A",
require: ["^mdChips", "^chipBar"],
controller: "chipBarController",
controllerAs: "chipBarController",
bindToController: {
activated: "="
},
// rest of the code
это позволяет установить активированный var в значение true из директивы; но теперь я не могу установить значение из моего appCtrl обратно в false
ее рабочий плункер с привязкой данных http://plnkr.co/edit/qtfEPfbNTZHHUEBhGYye?p=preview
есть много подробных чтений по сети
http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-2-isolate-scope
Вы должны создать переменную области видимости для своей директивы, чтобы директива могла узнать, какая переменная связывает ее
<div ng-controller="Controller">
{{email}} <== should become test on launch
<my-dialog email="email"></my-dialog>
<button ng-click="click()">click</button> <== should turn both in tst
</div>
<div class="alert">
email is :- {{email}}!
</div>
angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
$scope.email = '[email protected]';
$scope.click = function(){
$scope.email = "tst";
}
}])
.directive('myDialog', function() {
return {
restrict: 'E',
scope : { // this create an isolated scope
email:'=' // the email attribute is binded two way with '=', there is also '@' and '&'
},
templateUrl: 'my-dialog.html'
};
});
Обновление2 фактически устраняло проблему.
controllerAs: "chipBarController",
bindToController: {
activated: "="
},
сделал все, что нужно,
имел только опечатку в моем коде
Спасибо всем, кто помог, особенно @Claies
Я согласен с рекомендациями, говоря, что у вас, вероятно, проблема дизайна, но "плохо дает вам способ делать то, что вы хотите".
Используйте директиву ng-model и контроллер, после чего вы можете читать/наблюдать за изменением/изменением значения :)
См. Учебник здесь: https://www.nadeau.tv/using-ngmodelcontroller-with-custom-directives/
EDIT: хорошо, если вы можете использовать надлежащее связывание, у меня есть довольно грязный и хитрый способ сделать это: на основе этой документации: https://docs.angularjs.org/api/ng/function/angular.element
Добавьте атрибут, который будет содержать путь поля в виде строки в области контроллера (abc, если он в $ scope.abc), как это
Получите родительский элемент вашей директивы с помощью параметра angle.element() и получите его область действия с помощью метода scope (в документации). Затем вызовите метод $ eval, если эта область как это, чтобы прочитать theScope. $ Eval (attrs.fieldsPath); и с $ eval вы также сможете обновлять значения с помощью метода Object. $ eval (attrs. fieldsPath+ = 'myValue'). Если это не сработает, вам придется разделить строку на ".". и перемещаться по объекту области для записи в нужном поле.
var value = $scope;
var tab = attrs.fieldPath.split('.');
for(i = 0; i < tab.length && value; i++){
value = value[tab[i]];
}