2-х сторонняя директива по связыванию данных
Я смущен о 2-х сторонней привязке данных в угловых. Посмотри на код! var bah
может получить доступ к родительскому объекту $scope.something
но когда я нажимаю кнопку, значение в контроллере меняется на false
но не в директиве. в чем дело? это ошибка?
как это решить? спасибо, чтобы помочь мне, надеюсь, вы, пожалуйста, напишите пример или ссылки ref
HTML
<div ng-controller="myController">
show me something {{ something }} <br>
<button ng-click="toggleSomething"><button>
<!-- this is a canvas -->
<my-directive></my-directive>
</div>
JS
angular.module('fooBar',[]).controller('myController', ['$scope', function($scope) {
// this is the something
$scope.something = true;
$scope.toggleSomething = function(){
if($scope.something) {
$scope.something = false
} else {
$scope.something = true
}
}
}]).directive('myDirective', function(){
return {
template: '<canvas width="500px" height="500px"></canvas>',
link: function(scope, el, attr) {
//how to access that 'something'
var bah = scope.$parent.something;
}
};
});
ОБНОВЛЕНИЕ Действительно, спасибо вам всем. особенно тебе @immirza
мне так жаль, я не могу ответить вам один за другим. это просто добавить $parent
//how to access that 'something'
var bah = scope.$parent.something
3 ответа
Я установил планку с вашим кодом и добавил двустороннюю привязку к директиве. Вы можете увидеть это на PLNKR
angular.module('fooBar',[]).controller('myctr', ['$scope', function($scope) {
// this is the something
$scope.something = true;
$scope.toggleSomething = function(){
if($scope.something) {
$scope.something = false
} else {
$scope.something = true
}
}
}]).directive('myDirective', function(){
return {
//changed canvas to span so for simplixity.
template: '<span width="500px" height="500px">{{blah}} --- {{ dsomething }}</span>',
scope: { dsomething: "=" },
link: function(scope, el, attr) {
//watching $parent.variable is not recommonded as it makes your
//directive less reusable and forces who ever wants to use your
//directive to create the variable. dsomething will just update
//nicely w/o any code in this link function. the code below is just to demonstrate
//how to get it done by using $watch with $parent scope.
//how to access that 'something'
if(!scope.dsomething){
scope.dsomething = "something";
}
//because blah is a local variable and not a two-way binding variable
//we need to use $watch to update the value.
//you can use "dsomething" instead of "$parent.something"
//
scope.$watch("$parent.something", function(newVal, oldVal){
scope.blah = newVal;
})
}
};
});
Вы можете использовать свою директиву как:
<div ng-controller="myctr">
show me something {{ something }} <br />
<button ng-click="toggleSomething()">Update Something</button>
<button>
<!-- this is a canvas -->
<my-directive dsomething="something"></my-directive>
</button>
</div>
Обратите внимание на ng-click="toggleSomething()". это вызов функции, не передающий функцию. ng-click="toggleSomething" не будет работать.
Вы можете получить прямой доступ к $scope.something
в myDirective
без использования $parent
потому что директива shared scope
и на ваш вопрос, если вы пытаетесь обнаружить something
изменения внутри директивы вы не можете просто поставить console.log($scope.something)
и проверьте, потому что он выполняется только один раз, и после щелчка он не будет печатать снова, это не значит, something
не меняется внутри directive
,
а также вы сделали ошибку в ng-click
лайк ng-click="toggleSomething"
так должно быть ng-click="toggleSomething()"
так как вы вызываете функцию, а не просто переменную.
вот ДЕМО
я положил <h1> ... {{ something }}</h1>
внутри шаблона директивы, чтобы показать, что что-то работает, как и ожидалось, внутри директивы.
Пройдите эту превосходную серию директив
Проблема в том, что вы не понимаете, что такое двусторонняя привязка данных, в основном любой элемент, который two way bound
с директивой может быть обновлено контроллером или директивой, а другая немедленно увидит это изменение в ней.
Когда вы получаете доступ к нему с помощью $parent
вы принудительно читаете значение в вашей директиве, и ничего более, никто не говорит директиву для переоценки var bah = scope.$parent.something
как значение scope.something
был обновлен в родительском контроллере.