Bir AngularJS kapsam değişkenini yönergeden denetleyiciye geçirmenin en kolay yolu nedir? Gördüğüm tüm örnekler çok karmaşık görünüyor, bir denetleyiciye bir yönergeden erişip kapsam değişkenlerinden birini ayarlayabilmemin bir yolu yok mu?
Bir AngularJS kapsam değişkenini yönergeden denetleyiciye geçirmenin en kolay yolu nedir? Gördüğüm tüm örnekler çok karmaşık görünüyor, bir denetleyiciye bir yönergeden erişip kapsam değişkenlerinden birini ayarlayabilmemin bir yolu yok mu?
Yanıtlar:
2014/8/25 tarihinde düzenlendi: İşte onu çatalladığım yerdi .
Teşekkürler @anvarik.
İşte JSFiddle . Bunu nereye koyduğumu unuttum. Ama bu size = ve @ arasındaki farkı gösteren iyi bir örnek.
<div ng-controller="MyCtrl">
<h2>Parent Scope</h2>
<input ng-model="foo"> <i>// Update to see how parent scope interacts with component scope</i>
<br><br>
<!-- attribute-foo binds to a DOM attribute which is always
a string. That is why we are wrapping it in curly braces so
that it can be interpolated. -->
<my-component attribute-foo="{{foo}}" binding-foo="foo"
isolated-expression-foo="updateFoo(newFoo)" >
<h2>Attribute</h2>
<div>
<strong>get:</strong> {{isolatedAttributeFoo}}
</div>
<div>
<strong>set:</strong> <input ng-model="isolatedAttributeFoo">
<i>// This does not update the parent scope.</i>
</div>
<h2>Binding</h2>
<div>
<strong>get:</strong> {{isolatedBindingFoo}}
</div>
<div>
<strong>set:</strong> <input ng-model="isolatedBindingFoo">
<i>// This does update the parent scope.</i>
</div>
<h2>Expression</h2>
<div>
<input ng-model="isolatedFoo">
<button class="btn" ng-click="isolatedExpressionFoo({newFoo:isolatedFoo})">Submit</button>
<i>// And this calls a function on the parent scope.</i>
</div>
</my-component>
</div>
var myModule = angular.module('myModule', [])
.directive('myComponent', function () {
return {
restrict:'E',
scope:{
/* NOTE: Normally I would set my attributes and bindings
to be the same name but I wanted to delineate between
parent and isolated scope. */
isolatedAttributeFoo:'@attributeFoo',
isolatedBindingFoo:'=bindingFoo',
isolatedExpressionFoo:'&'
}
};
})
.controller('MyCtrl', ['$scope', function ($scope) {
$scope.foo = 'Hello!';
$scope.updateFoo = function (newFoo) {
$scope.foo = newFoo;
}
}]);
Bununla çok uğraştım "="
ve kapsamda tanımlanan değişkenle bile çalışmasını sağlayamadım . Durumunuza bağlı olarak işte üç çözüm.
Yönergeye geçildiğinde değişkenin henüz açısal olarak değerlendirilmediğini buldum . Bu, ona erişip şablonda kullanabileceğiniz anlamına gelir, ancak değerlendirilmesini beklemediğimiz sürece bağlantı veya uygulama denetleyici işlevi içinde olamaz.
Senin Eğer değişken değişiyor ya da bir istek üzerinden alınıyor, sen kullanmalısınız $observe
veya $watch
:
app.directive('yourDirective', function () {
return {
restrict: 'A',
// NB: no isolated scope!!
link: function (scope, element, attrs) {
// observe changes in attribute - could also be scope.$watch
attrs.$observe('yourDirective', function (value) {
if (value) {
console.log(value);
// pass value to app controller
scope.variable = value;
}
});
},
// the variable is available in directive controller,
// and can be fetched as done in link function
controller: ['$scope', '$element', '$attrs',
function ($scope, $element, $attrs) {
// observe changes in attribute - could also be scope.$watch
$attrs.$observe('yourDirective', function (value) {
if (value) {
console.log(value);
// pass value to app controller
$scope.variable = value;
}
});
}
]
};
})
.controller('MyCtrl', ['$scope', function ($scope) {
// variable passed to app controller
$scope.$watch('variable', function (value) {
if (value) {
console.log(value);
}
});
}]);
Ve işte html (köşeli parantezleri unutmayın!):
<div ng-controller="MyCtrl">
<div your-directive="{{ someObject.someVariable }}"></div>
<!-- use ng-bind in stead of {{ }}, when you can to avoids FOUC -->
<div ng-bind="variable"></div>
</div>
Fonksiyonu "="
kullanıyorsanız, değişkeni kapsamda olarak ayarlamamanız gerektiğini unutmayın $observe
. Ayrıca, nesneleri dizeler olarak ilettiğini buldum, bu nedenle nesneleri geçiriyorsanız çözüm # 2 veya scope.$watch(attrs.yourDirective, fn)
(veya değişkeniniz değişmiyorsa # 3 ) kullanın.
Senin Eğer değişken örneğin başka bir kontrol oluşturulur , ama sadece açısal uygulaması kontrolöre göndermeden önce değerlendirilir beklemeniz gerekir kullanabileceğimiz $timeout
kadar beklemek $apply
tükendi. Ayrıca bunu $emit
üst kapsam uygulama denetleyicisine göndermek için kullanmamız gerekir (yönergedeki yalıtılmış kapsam nedeniyle):
app.directive('yourDirective', ['$timeout', function ($timeout) {
return {
restrict: 'A',
// NB: isolated scope!!
scope: {
yourDirective: '='
},
link: function (scope, element, attrs) {
// wait until after $apply
$timeout(function(){
console.log(scope.yourDirective);
// use scope.$emit to pass it to controller
scope.$emit('notification', scope.yourDirective);
});
},
// the variable is available in directive controller,
// and can be fetched as done in link function
controller: [ '$scope', function ($scope) {
// wait until after $apply
$timeout(function(){
console.log($scope.yourDirective);
// use $scope.$emit to pass it to controller
$scope.$emit('notification', scope.yourDirective);
});
}]
};
}])
.controller('MyCtrl', ['$scope', function ($scope) {
// variable passed to app controller
$scope.$on('notification', function (evt, value) {
console.log(value);
$scope.variable = value;
});
}]);
Ve işte html (parantez yok!):
<div ng-controller="MyCtrl">
<div your-directive="someObject.someVariable"></div>
<!-- use ng-bind in stead of {{ }}, when you can to avoids FOUC -->
<div ng-bind="variable"></div>
</div>
Senin Eğer değişken değişmemektedir ve size yönergede değerlendirmek gerekir kullanabilirsiniz $eval
işlevi:
app.directive('yourDirective', function () {
return {
restrict: 'A',
// NB: no isolated scope!!
link: function (scope, element, attrs) {
// executes the expression on the current scope returning the result
// and adds it to the scope
scope.variable = scope.$eval(attrs.yourDirective);
console.log(scope.variable);
},
// the variable is available in directive controller,
// and can be fetched as done in link function
controller: ['$scope', '$element', '$attrs',
function ($scope, $element, $attrs) {
// executes the expression on the current scope returning the result
// and adds it to the scope
scope.variable = scope.$eval($attrs.yourDirective);
console.log($scope.variable);
}
]
};
})
.controller('MyCtrl', ['$scope', function ($scope) {
// variable passed to app controller
$scope.$watch('variable', function (value) {
if (value) {
console.log(value);
}
});
}]);
Ve işte html (köşeli parantezleri unutmayın!):
<div ng-controller="MyCtrl">
<div your-directive="{{ someObject.someVariable }}"></div>
<!-- use ng-bind instead of {{ }}, when you can to avoids FOUC -->
<div ng-bind="variable"></div>
</div>
Ayrıca, şu yanıta bir göz atın: https://stackoverflow.com/a/12372494/1008519
FOUC (biçimlendirilmemiş içeriğin flaşı) sorunu için referans: http://deansofer.com/posts/view/14/AngularJs-Tips-and-Tricks-UPDATED
İlgilenenler için: işte açısal yaşam döngüsü üzerine bir makale
ng-if="someObject.someVariable"
direktif (veya bir öznitelik olarak direktifi içeren öğe) üzerine bir basitlik yeterlidir - direktif ancak someObject.someVariable
tanımlandıktan sonra devreye girer .