지시문에서 컨트롤러로 AngularJS 범위 변수를 전달하는 가장 쉬운 방법은 무엇입니까?
지시문에서 컨트롤러로 AngularJS 범위 변수를 전달하는 가장 쉬운 방법은 무엇입니까? 내가 본 모든 예제가 너무 복잡해 보이지만 지시문에서 컨트롤러에 액세스하고 범위 변수 중 하나를 설정할 수있는 방법이 없습니까?
2014/8/25에 편집 : 여기 에서 분기했습니다.
감사합니다 @anvarik.
다음은 JSFiddle 입니다. 어디서 포크했는지 잊었습니다. 그러나 이것은 =와 @의 차이점을 보여주는 좋은 예입니다.
<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;
}
}]);
angular가 변수를 평가할 때까지 기다리십시오.
나는 이것을 많이 다루었 고 "="
스코프에서 정의 된 변수로도 작동하지 못했습니다 . 상황에 따른 세 가지 해결책이 있습니다.
솔루션 # 1
변수가 지시문에 전달되었을 때 아직 각도로 평가되지 않았 음을 발견 했습니다 . 즉, 평가를 기다리지 않는 한 링크 또는 앱 컨트롤러 함수 내부에서 액세스하여 템플릿에서 사용할 수 있습니다.
귀하의 경우 변수가 변화하고 , 또는 요청을 통해 가져온, 당신은 사용해야 $observe
또는 $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);
}
});
}]);
그리고 여기에 html이 있습니다 (괄호를 기억하세요!) :
<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>
함수를 "="
사용하는 경우 범위에서 변수를 로 설정해서는 안됩니다 $observe
. 또한 개체를 문자열로 전달하므로 개체를 전달하는 경우 솔루션 # 2 또는 scope.$watch(attrs.yourDirective, fn)
(또는 변수가 변경되지 않으면 # 3 )을 사용합니다.
솔루션 # 2
If your variable is created in e.g. another controller, but just need to wait until angular has evaluated it before sending it to the app controller, we can use $timeout
to wait until the $apply
has run. Also we need to use $emit
to send it to the parent scope app controller (due to the isolated scope in the directive):
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;
});
}]);
And here's the html (no brackets!):
<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>
Solution #3
If your variable is not changing and you need to evaluate it in your directive, you can use the $eval
function:
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);
}
});
}]);
And here's the html (remember the brackets!):
<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>
Also, have a look at this answer: https://stackoverflow.com/a/12372494/1008519
Reference for FOUC (flash of unstyled content) issue: http://deansofer.com/posts/view/14/AngularJs-Tips-and-Tricks-UPDATED
For the interested: here's an article on the angular life cycle
'Programing' 카테고리의 다른 글
Java Date & Time API의 문제점은 무엇입니까? (0) | 2020.08.21 |
---|---|
Elastic Search : 인덱싱 된 데이터를 보는 방법 (0) | 2020.08.21 |
인터넷 연결이 없으면 Spring schemaLocation이 실패합니다. (0) | 2020.08.20 |
logback.xml의 XML 스키마 또는 DTD? (0) | 2020.08.20 |
SQL 기본 키 및 색인 (0) | 2020.08.20 |