【问题标题】:Angular: UI.Router resolves & controller code duplicationAngular:UI.Router 解决和控制器代码重复
【发布时间】:2016-02-28 18:13:03
【问题描述】:

我一直在重构我的应用程序以利用 UI.Router 的 state.resolve 来清理一些控制器逻辑。但是后来我开始遇到以下问题:如何避免在获取已解析资产中的依赖项以及更新控制器内的数据时发现的代码重复?

状态

$stateProvider.state 'someState', state =
    controller: 'SomeController'
    controllerAs: 'vc'
    resolve: { viewData: [
        '$http'
        '$q'
        '$stateParams'
        'someService'
        ($http, $q, $stateParams, someService)->
           someService.get $stateParams.id
           .then (rsp)-> rsp
           .catch (err)-> $q.reject err
]}

视图控制器

class SomeController
    constructor: (@$http, @$q, @$stateParams, @someService, @viewData)->
        # non-Coffee FYI - @arg is the same as "this.arg = arg"

    getViewData: ->
        someService.get @$stateParams.id
        .then (rsp)-> @viewData = rsp
        .catch (err)-> $q.reject err

** 一些服务**

class SomeService
    constructor: (@$http, @$q)->

    get: (id)->
        $http.get "/url/#{id}"
        .then (rsp)-> rsp.data?.data
        .catch (err)-> $q.reject err

状态的resolved viewData 函数与控制器的 getViewData 调用几乎相同。这似乎非常多余。利用相同代码的任何技巧?

我什至在考虑将一个函数传回已解析的对象中,该函数可以分配给控制器,当它需要执行相同的逻辑时它可以利用它,但我无法弄清楚(非 ng)范围问题.

现实生活

  1. 进入状态,resolve 对象获取初始viewData
  2. 当前viewData 已设置状态的控制器和 UI 渲染
  3. 视图控制器每 x 分钟轮询 get 服务以检查 viewData 的更新

【问题讨论】:

  • 视情况而定。 'url' 在所有情况下都相同吗? 'viewData' 中的 $http 请求应该在每个状态解析时执行还是只执行一次?
  • 在尝试理解您的意思后,我注意到我完全忘记了服务代码。这可能需要一个更广泛的例子,因为目前它非常微不足道。所以是的,无论是调用它的 resolve 对象还是视图控制器,URL 都是相同的。就每一次与一次的问题而言,我不确定我是否遵循。如果这就是你的意思,它不会被缓存。
  • 我猜这和路由解析器的情况差不多。
  • 这对我来说不是问题,因为我使用父状态来处理任何继承的已解析依赖项。这个特定的viewData 请求对于视图来说是唯一的,这意味着没有其他路由/状态会使用它。重复之处在于已解决的依赖项和随后的控制器请求几乎相同。又是一个非常微不足道的例子,但我试图尽可能简洁

标签: angularjs coffeescript angular-ui-router resolve


【解决方案1】:

必须将公共代码段分离为服务并包装在函数中:

app.factory('viewDataService', function ($http, $q, $stateParams, someService) {
  return function () {
    return someService.get($stateParams.id).then(function(rsp) {
      return rsp;
    })["catch"](function(err) {
      return $q.reject(err);
    });
  }
});

here所示,这样someService.get可以在每次注入服务时调用

resolve: {
  viewData: function (viewDataService) {
    return viewDataService();
  }
}

【讨论】:

  • 我将把它标记为答案,因为它是正确的,我只是希望当可能需要在服务调用之外执行逻辑时找到更好的方法来封装它(例如拉 $stateParams)但我必须将该逻辑传递给服务。
  • @jusopi 从外部传递参数作为 viewDataService 函数参数对我来说看起来不错,这确保了可测试性。但也许我误解了你,如果你仍然有关于这个主题的问题,请随时使用当前代码发布问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多