directive 组件化拆分页面的时候碰到如下问题:
页面 ctrl 会加载 base 数据。各个组件(directive)也有各自的数据。因为 promise 的缘故,ctrl 和 directive 直接相互是不知道对方数据加载状态的。但是页面加载完成后我需要立即使用 base 数据+组件的数据(比如一些必选项)去读取价格。
我自己的思路大致如下:
1、让组件完全独立。也就是组件的link函数还是去读取一次base数据。
2、页面 ctrl 在加载 base 数据之后 broadcast 一次,然后组件再去读取相关数据进行处理。
希望得到的答案是:那种方式更优以及为什么,谢谢。(当然,欢迎更多其它思路。)
怪我咯2017-04-10 17:03:21
我做过的方法是将base数据放在一个service中,它要记录是否正在运行的状态,保证即使被多次调用,也执行一次数据获取,获取后将结果放在一个变量中。controller中用一个变量指向service的结果,watch这个变量,获得了有效数据后,执行后续操作。
PHPz2017-04-10 17:03:21
在项目中我的做法是这样的:
发起事件者 一般来说是页面的 Ctrl, 调用 service 的异步数据操作, 并告诉service广播事件的名称('something.ctrl.concerned').
service数据操作后, 广播这个事件($rootScope.$broadcast('something.ctrl.concerned', data))
, 且通过 deferred.resolve(data);
直接发起者可以使用 promise.then(function (data){})
的形式处理
其他感兴趣的一些指令, 同样也可以接听这个数据更新后的广播, 做出相应的操作. $scope.$on('something.ctrl.concerned', function (event, data) { .... })
;
PHPz2017-04-10 17:03:21
按照你的意思就是,数据之间存在关系,只有数据都拿到的情况下才可以计算出价格,用$q.all去处理吧。
可以参考这个读文件获得dashboard的数据的例子用ES6写的
https://github.com/hjzheng/angular-es6-practice/blob/master/src/app/index.route.js
看看file service的写法(非ES6)
(function() {
'use strict';
angular
.module('app.common')
.factory('file', factory);
factory.$inject = ['$http', '$q'];
/* @ngInject */
function factory($http, $q) {
var service = {
getFiles: getFiles
};
return service;
////////////////
function getFiles(files) {
var promises = files.map(function(file) {
return $http.get(file);
});
return $q.all(promises);
}
}
})();