对我的父控制器做出反应以完成加载

reacting on my parent controller to be done with loading

我有一个通过 RestAngular 加载对象数组的 MainController

controllers.controller('MainController', $scope, Restangular) {
    $scope.colors = {};
    Restangular.all('colors').getList().then(function(colors) {
        angular.forEach(colors, function(c) {
            c.brightness = getBrightness(c);
            $scope.colors[c.id] = c;
        });
    });
};

而且我有一个路由来处理颜色的子页面。

$stateProvider
   .state('picture', {
           abstract: true,
           url: "/picture/{pictureId:[0-9]{1,6}}",
           templateUrl: "partials/picture.html",
           controller: 'MainController'
          }
   )
   .state('picture.colors', {
           url: "/colors",
           templateUrl: "partials/picture_colors.html",
           controller: 'PictureColorsController'
           }
   );

在这里,我想要一个多select颜色的下拉菜单。

<multiselect ng-model="selector.colors"
             options="c as c.name for c in colors| orderBy:'brightness'"
             data-multiple="true"
             header="Colors">
</multiselect>

这很好用。但是当页面加载时,我希望所有颜色都被 selected。所以我想要的是:

controllers.controller('PictureColorsController', $scope) {
    $scope.selector = {colors:[]};
    var selectAll = function() {
        $scope.selector.colors.splice(0, $scope.selector.colors.length);
        angular.forEach($scope.colors, function(c) {
            $scope.selector.colors.push(c);
        });
    };
    selectAll();
};

但是在子控制器 'PictureColorController' 执行时,颜色还没有加载。所以我能想到的唯一解决方案是跟随,但我不太喜欢它。感觉自己做错了什么。

controllers.controller('MainController', $scope, Restangular) {
    $scope.colors = {};
    var colorsCallback = undefined;
    $scope.registerColorsCallbackFn = function(func) {
        colorsCallback = func;
    };
    Restangular.all('colors').getList().then(function(colors) {
        angular.forEach(colors, function(c) {
            c.brightness = getBrightness(c);
            $scope.colors[c.id] = c;
        });
        if (colorsCallback) {
            colorsCallback();
        }
    });
};

controllers.controller('PictureColorsController', $scope) {
    $scope.selector = {colors:[]};
    var selectAll = function() {
        $scope.selector.colors.splice(0, $scope.selector.colors.length);
        angular.forEach($scope.colors, function(c) {
            $scope.selector.colors.push(c);
        });
    };
    selectAll();
    $scope.registerColorsCallbackFn(selectAll);
};

有没有更简洁的方法来做到这一点?我想在我的 MainController 中加载几个数据列表,在我想执行任何子控制器之前都需要加载这些数据。有什么好的机制吗?

您可以在状态下使用 ui-路由器的 resolve 属性:

.state('picture.colors', {
           url: "/colors",
           templateUrl: "partials/picture_colors.html",
           controller: 'PictureColorsController'
           },
           resolve: {
             colors: function(Restangular) {
               return Restangular.all('colors').getList();
             }
           }
   )

ui-router 将在执行控制器之前解析 resolve 对象中的每个 promise。它会给你一个 colors 参数,你可以用 promise 解析的数据注入你的控制器。

不过,您的方法不一定有任何问题。一个稍微更结构化的版本是 John Papa Angular style guide.

中的方法之一