Angular ui-router从列表中解析

时间:2015-12-09 16:05:01

标签: angularjs

我要做的是使用循环解决我需要的项目而不是为该项目创建API请求,因为我已经在内存中有该项目。

所以,我有一个列表,如果我的服务中的项目,当我点击进入项目详细信息时,我这样做:

.state('app.itemDetails', {
        url: '/items/:itemId',
        templateUrl: 'modules/items/views/items.details.view.html',
        controller: 'DetailsController',
        resolve: angular.extend(
            helper.resolveFor('ngDialog'), {
                item: function ($q, $stateParams, itemsManager) {
                    var deferred = $q.defer();
                    var obj = {};
                    var promise = _.each(itemsManager.list, function (item) {
                        if (item.id === $stateParams.itemId) {
                            obj = item;
                        }
                        return $q.when(obj);
                    });

                    $q.all(promise).then(function (item) {
                        deferred.resolve(item);
                    });

                    return deferred.promise;
                }
            }
        )
    })

看起来它绕过了_.each并且总是返回相同的项目...... 我怎么处理呢?

编辑:

// Generates a resolve object by passing script names
  // previously configured in constant.APP_REQUIRES
  this.resolveFor = function () {
    var _args = arguments;
    return {
      deps: ['$ocLazyLoad','$q', function ($ocLL, $q) {
        // Creates a promise chain for each argument
        var promise = $q.when(1); // empty promise
        for(var i=0, len=_args.length; i < len; i ++){
          promise = andThen(_args[i]);
        }
        return promise;

        // creates promise to chain dynamically
        function andThen(_arg) {
          // also support a function that returns a promise
          if(typeof _arg == 'function')
              return promise.then(_arg);
          else
              return promise.then(function() {
                // if is a module, pass the name. If not, pass the array
                var whatToLoad = getRequired(_arg);
                // simple error check
                if(!whatToLoad) return $.error('Route resolve: Bad resource name [' + _arg + ']');
                // finally, return a promise
                return $ocLL.load( whatToLoad );
              });
        }
        // check and returns required data
        // analyze module items with the form [name: '', files: []]
        // and also simple array of script files (for not angular js)
        function getRequired(name) {
          if (appRequires.modules)
              for(var m in appRequires.modules)
                  if(appRequires.modules[m].name && appRequires.modules[m].name === name)
                      return appRequires.modules[m];
          return appRequires.scripts && appRequires.scripts[name];
        }

      }]};
  }; // resolveFor

编辑2:

                    var id = $stateParams.itemId;
                    return _.each(ItemsManager.list, function (item) {
                        if (item.id == id) {
                            console.log('found');
                            console.log(item);
                            return item;
                        }
                    });

在console.log中,我正确收到了该项目。视图没有收到它......

3 个答案:

答案 0 :(得分:1)

_.each不会返回您在谓词中返回的内容。请改用_.map_.map将返回您在谓词中返回的对象数组。

查看docs

此外,还不完全清楚你要做什么。您不需要返回承诺。如果您只想返回itemsManager.list中与$stateParams.itemId对应的项目,则可以使用

    item: function ($stateParams, itemsManager){
     return _.find(itemsManager.list, 
            function(item){
              return item.id === $stateParams.itemId;
            }
         );
}

并返回该特定项目。

答案 1 :(得分:1)

为什么不简单地这样做??

item: function ($q, $stateParams, itemsManager) {
    var deferred = $q.defer();
    _.each(itemsManager.list, function (item) {
        if (item.id === $stateParams.itemId) {
            deferred.resolve(item);
            return false; //stop iterating
        }
        return true;
    });

    return deferred.promise;
}

我假设只有一个项目符合条件

更新:第二个想法我认为在那里使用一个承诺是没用的,执行将在迭代中被阻止。您可以直接返回找到的项目,状态中的 resolve 属性可以使用一个函数来定义,该函数也会返回一个值而不是一个promise。

item: function ($stateParams, itemsManager) {
    var obj;
    _.each(itemsManager.list, function (item) {
        if (item.id === $stateParams.itemId) {
            obj = item;
            return false; //stop iterating
        }
        return true;
    });

    return obj;
}

答案 2 :(得分:0)

您可以使用_.find而不是遍历整个列表。

var item = _.find(itemsManager.list,{id:$ stateParams.itemId});