重构。如何解除对服务的调用和$ scope值的修改?

时间:2014-10-02 18:38:32

标签: angularjs refactoring

我们正在使用两种模式:。每一天都属于一周。

我们有两种观点:周细节日期细节

我们如何将Calls to Service和$ scope值修改分离?

(可能使用AngularJS指令)

周细节视图具有以下模板,列出了属于特定周的所有日期

<!-- file 1: week-detail.tpl.html -->
<table>
  <tr ng-repeat="day in weekdetail.days">
    <td>
      <span ng-click="toggleActive(day.id, $index)">
        {{ day.active }}
      </span>
    </td>
  </tr>
</table>

命令此视图的Controller如下:

// file 2: week-detail.controller.js
function WeekDetailCtrl ($scope, $routeParams, Week, Days, DayToggleActive) {
  this.week = Week.get({ id: $routeParams.id });
  this.days = Days.query({ id: $routeParams.id });

  // @param dayId: id to be processed by DayToggleActvive.toggleActive() service
  // @param position: $index from ng-repeat, to modify this specific DOM element
  $scope.toggleActive = function(dayId, position) {
    // call to service
    (DayToggleActive.toggleActive({ id: dayId }))
      .$promise
        .then(function(data) {
           // $scope values manipulation
           $scope.weekdetail.week = data;
           $scope.weekdetail.days[position].active = !$scope.weekdetail.days[position].active;
        });
  };
}

日详细信息视图具有以下模板:

<!-- file 3: day-detail.tpl.html -->
<div ng-click="toggleDetailActive(daydetail.day.id)">
    {{ daydetail.day.active }}
</div>

命令此视图的Controller如下:

// file 4: day-detail.controller.js
function DayDetailCtrl ($scope, $routeParams, Day, DayToggleActive) {
  this.day = Day.get({ id: $routeParams.id });
  this.ods = Ods.query({ id: $routeParams.id });

  // @param dayId: id to be processed by DayToggleActvive.toggleActive() service
  $scope.toggleDetailActive = function(dayId) {
    // call to same service
    (DayToggleActive.toggleActive({ id: dayId }))
      .$promise
        .then(function(data) {
          // $scope value manipulation is different in Day Detail View
          $scope.daydetail.day.active = !$scope.daydetail.day.active;
        });
  };
}

提前感谢您的帮助


更新

感谢help of Oddman,我们继续进行了

我们已向HTML添加了自定义指令标记

<!-- file 3: day-detail.tpl.html -->
<div toggleActive="daydetail.day">
    {{ daydetail.day.active }}
</div>

并将指令添加到模块

// file 4: day-detail.controller.js
module.directive('toggleActive', toggleActive);

function toggleActive() {
  return {
    scope: {day: '=toggleActive'},
    restrict: "A",
    link: function(scope, element, attrs ) {
      element.bind("click", function() {
        scope.day.active = !scope.day.active;
      });
    }
  }
}

看起来更好,但是...我们需要的是在成功调用Service之后切换scope.day.active,所以......

// file 4: day-detail.controller.js
// inject DayToggleActive service dependency
module.directive('toggleActive', ['DayToggleActive', toggleActive]);

function toggleActive(DayToggleActive) {
  return {
    scope: {day: '=toggleActive'},
    restrict: "A",
    link: function(scope, element, attrs ) {
      element.bind("click", function() {
      (DayToggleActive.toggleActive({ id: scope.day.id }))
        .$promise
          .then(function(data) {
            scope.day.active = !scope.day.active;
          })
          .catch(function(response) {
            console.log(response);
          });
      });
    }
  }
}

以前,引用是在控制器声明中,所以让我们将其删除

// file 4: day-detail.controller.js
function DayDetailCtrl ($scope, $routeParams, Day) {
...

立即

周细节视图可以以相同的方式重构

<!-- file 1: week-detail.tpl.html -->
<table>
  <tr ng-repeat="day in weekdetail.days">
    <td>
      <span toggleDayActive="day">
        {{ day.active }}
      </span>
    </td>
  </tr>
</table>

日间细节控制器将包含我们为周细节控制器

定义的类似指令
// file 2: week-detail.controller.js
// inject DayToggleActive service dependency
module.directive('toggleDayActive', ['DayToggleActive', toggleDayActive]);

function toggleDayActive(DayToggleActive) {
  return {
    scope: {day: '=toggleDayActive'},
    restrict: "A",
    link: function(scope, element, attrs ) {
      element.bind("click", function() {
      (DayToggleActive.toggleActive({ id: scope.day.id }))
        .$promise
          .then(function(data) {
            scope.day.active = !scope.day.active;
            // HOW COULD WE ACCESS PREVIUSLY REFERENCED AS $scope.weekdetail.week ?
          })
          .catch(function(response) {
            console.log(response);
          });
      });
    }
  }
}

我们怎样才能重新获得以前引用为$ scope.weekdetail.week的访问权限? 我们是否需要以某种方式将其作为参数传递? 有没有办法达到$ scope?

1 个答案:

答案 0 :(得分:0)

我会为你的切换设置指令,然后将这一天或一周传递给它。例如:

<div toggle-week="week"></div>

然后在你的指令中,例如:

module.directive('toggleWeek', function() {
    return {
        scope: {week: '=toggleWeek'},
        link: function(scope, element, attrs) {
            // add your scope function here
        }
    };
});

您可以为日常切换做类似的事情。然后你就可以在你的指令中处理周/日绑定,而不是直接在$ scope上工作。

希望有所帮助。