Øys*_*sen 4 angularjs angularjs-scope
我试图找出在控制器/指令之间共享属性或状态的"首选"或"角度方式".有几种方法可以实现这一点,但我希望保持最佳实践.以下是一些如何实现此功能的平庸示例:
1.使用$ scope.$ watch
// The parent controller/scope
angular.module('myModule').controller('parentController', ['$scope', function($scope) {
$scope.state = {
myProperty: 'someState'; // Default value to be changed by some DOM element
};
}]);
// The child controller/scope.
angular.module('myModule').controller('childController', ['$scope', function($scope) {
$scope.$watch('state.myProperty', function (newVal) {
// Do some action here on state change
});
}]);
Run Code Online (Sandbox Code Playgroud)
编辑:根据下面的答案,这是不好的做法,应该避免.它是不可测试的并且放置了不需要的DOM依赖性.
2.使用$ broadcast
// The parent controller
angular.module('myModule').controller('parentController', ['$scope', function($scope) {
var myProperty = 'someState';
$scope.setState = function (state) {
myProperty = state; // Set by some other controller action or DOM interaction.
$scope.$broadcast('stateChanged', state); // Communicate changes to child controller
}
}]);
// The child controller.
angular.module('myModule').controller('childController', ['$scope', function($scope) {
$scope.$on('stateChanged', function (evt, state) {
// Do some action here
}
}]);
Run Code Online (Sandbox Code Playgroud)
编辑:同样糟糕的做法,因为你需要知道控制器在DOM中的位置,以确定使用$ broadcast(下行DOM)或$ emit(上行DOM)的天气.
3.使用服务
angular.module('myModule').factory('stateContainer', [function () {
var state = {
myProperty: 'defaultState'
},
listeners = [];
return {
setState: function (newState) {
state.myProperty = newState;
angular.forEach(listeners, function (listener) {
listener(newState);
});
},
addListener: function (listener) {
listeners.push(listener);
}
}
}]);
// The parent controller
angular.module('myModule').controller('parentController', ['$scope', 'stateContainer', function($scope, stateContainer) {
$scope.setState = function (state) {
stateContainer.setState(state);
};
}]);
// The child controller.
angular.module('myModule').controller('childController', ['$scope', 'stateContainer', function($scope, stateContainer) {
stateContainer.addListener(function (newState) {
// Do some action here
});
}]);
Run Code Online (Sandbox Code Playgroud)
可能有一些我在这里错过的方法,但你明白了.我正在努力寻找最好的方法.虽然冗长,但我个人倾向于列表中的#3.但我来自Java和jQuery背景,其中听众被广泛使用.
编辑:下面的答案很有见地.一个讲述了使用require指令配置在父/子指令之间共享状态.另一个是直接与范围共享服务或服务属性的讨论.我相信,根据需要,他们在Angular的最佳实践中是正确的.
如果正确完成,任何这些都将有效,但服务上的变体是AFAIK的首选方式.
问题是,你甚至需要服务案例中的听众吗?Angular本身会更新任何视图(这是控制器的目的),那么为什么需要监听器或监听?对于要更改的视图,更改值本身就足够了.
app.factory('stateService',function() {
return {
myState: "foo"
}
})
.controller('one',function($scope,stateService) {
$scope.changeState = function() {
stateService.myState = $scope.state;
};
})
.controller('two',function($scope,stateService) {
$scope.svc = stateService;
})
Run Code Online (Sandbox Code Playgroud)
然后,您可以在视图中执行以下操作(不完整):
<div ng-controller="one">
<input name="state" ng-model="state"></input>
<button type="submit" ng-click="changeState()">Submit</button>
</div>
<div ng-controller="two">{{svc.myState}}</div>
Run Code Online (Sandbox Code Playgroud)
事实上,你甚至不需要通过按钮和功能去那么远.如果你只是将ng-model它们绑在一起它将起作用:
<div ng-controller="one">
<input name="state" ng-model="svc.myState"></input>
</div>
<div ng-controller="two">{{svc.myState}}</div>
Run Code Online (Sandbox Code Playgroud)
试试下面的jsfiddle http://jsfiddle.net/cwt9L6vn/1/
| 归档时间: |
|
| 查看次数: |
2584 次 |
| 最近记录: |