gpt4 book ai didi

angularjs - Controller 间通信, Angular 方式

转载 作者:行者123 更新时间:2023-12-04 23:48:39 25 4
gpt4 key购买 nike

我试图找出在 Controller /指令之间共享属性或状态的“首选”或“Angular 方式”。有几种方法可以实现这一点,但我想保持最佳实践。下面是一些关于如何实现这一点的平庸示例:

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
});
}]);

编辑:根据下面的答案,这是不好的做法,应该避免。它是不可测试的,并放置了不需要的 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
}
}]);

编辑:同样不好的做法,因为您需要知道 Controller 在 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
});
}]);

我可能在这里错过了一些方法,但你明白了。我正在努力寻找最好的方法。虽然冗长,但我个人倾向于此处列表中的 #3。但我来自广泛使用监听器的 Java 和 jQuery 背景。

编辑:下面的答案很有见地。使用 require 在父/子指令之间共享状态的讨论指令配置。另一个是直接向范围共享服务或服务属性。我相信,根据需要,它们在 Angular 中的最佳实践是什么或不是什么方面都是正确的。

最佳答案

如果正确完成,这些中的任何一个都可以工作,但服务的变体是 AFAIK 的首选方式。

问题是,在服务案例中你甚至需要一个监听器吗? Angular 本身会更新任何 View (这是 Controller 的目的),那么为什么需要监听器或观察器呢?对于要更改的 View ,更改值本身就足够了。

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;
})

然后,您可以在您的 View 中执行以下操作(不完整):
<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>

事实是,您甚至不需要拥有一个按钮和一个功能就走那么远。如果你只是绑 ng-model一起工作:
<div ng-controller="one">
<input name="state" ng-model="svc.myState"></input>
</div>
<div ng-controller="two">{{svc.myState}}</div>

试试下面的 jsfiddle http://jsfiddle.net/cwt9L6vn/1/

关于angularjs - Controller 间通信, Angular 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28002537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com