繁体   English   中英

修改视图的AngularJS最佳实践

[英]AngularJS Best Practices for modifying view

我目前有一个带有一个模块的Angular应用程序。 该模块定义了控制器和服务。 我目前正在使用该服务来更新我的视图。 服务应该更新视图逻辑吗? 还是应该在单独的Angular组件中完成?

index.html

<div ng-controller="AppController as AppCtrl">
  <div id="grid1" ui-grid="{ data: myData }" class="grid"></div>
  <button ng-click="AppCtrl.getPeople()" ng-model="AppCtrl.getPeopleButtonText" ng-bind="AppCtrl.getPeopleButtonText"></button>
  <button ng-click="AppCtrl.clearPeople()">Clear</button>
  {{AppCtrl.errorMessage}}
</div>

app.js

angular.module('app', ['ui.grid'])
  .controller('AppController', ['$scope', "PersonService", function ($scope, PersonService) {

    var controllerScope = this;
    controllerScope.getPeopleButtonText = "Get People";

    this.getPeople = function(){
      PersonService.getPeople($scope, controllerScope);
    };

    this.clearPeople = function(){
      PersonService.clearPeople($scope, controllerScope);
    };
  }])
  .service("PersonService", ["$http", function($http) {

    var refreshCount = 0;
    this.getPeople = function(rootScope, controllerScope){

          var sampleData = [
        {
            "firstName": "Cox",
            "lastName": "Carney",
            "company": "Enormo",
            "employed": refreshCount%2 == 1
        },
        {
            "firstName": "Lorraine",
            "lastName": "Wise",
            "company": "Comveyer",
            "employed": refreshCount%2 == 0
        },
        {
            "firstName": "Nancy",
            "lastName": "Waters",
            "company": "Fuelton",
            "employed": refreshCount%2 == 1
        }
      ];

      $http.post("https://httpbin.org/post", sampleData)
        .success(function(data){
          rootScope.myData = JSON.parse(data.data);
          refreshCount++;
          controllerScope.getPeopleButtonText = "Refresh " + refreshCount;
          controllerScope.errorMessage = "";
        })
        .error(function() {
          controllerScope.errorMessage = "An error has occurred."
        });
    };

    this.clearPeople = function(rootScope, controllerScope) {
      rootScope.myData = [];
      controllerScope.getPeopleButtonText = "Get People";
    }
}]);

有没有更好的方法来构造此代码? 我已了解的另一种方法是创建ViewService并将ViewService公开到根作用域中。

编辑11月19日我正在使用Angular Promise在控制器中而不是在服务内部处理服务调用的成功/错误情况。 这使我可以将视图更新移至控制器中。 这是保持视图更新的正确位置吗?

this.getPeople = function() {
  PersonService.getPeople()
    .then(function(data) {
      $scope.myData = JSON.parse(data);
      controllerScope.getPeopleButtonText = "Refresh";
      controllerScope.errorMessage = "";
    }, function(error) {
      controllerScope.errorMessage = "An error has occurred."
    });
};

这是一个示例plnkr http://plnkr.co/edit/tzuSX3aAcUqpH5bM7cIa?p=preview

  1. 切勿使用$rootScope存储数据
  2. 如果愿意,请使用MVC模式,因此:

一个视图只有一个控制器,可以根据需要提供尽可能多的服务。

  • 您的视图显示了$scope
  • 您的控制器正在从您的PersonService获取数据
  • PersonService(或仅API服务)从后端获取数据。

最佳做法如下( 简明 ):

Api.js

angular
    .module( 'api', [])
    .service('Api', Api);

Api.$inject = ['$http'];

function Api($http) {

    var baseUrl = '/api/url/';

    function getPersons() {
        return $http({
            method: 'GET',
            url: baseUrl + 'YOUR/PERSON/URL'
        });
    }

    return {
       getPersons: getPersons
    }
}

PersonController.js

angular
  .module('personApp')
  .controller('PersonController', PersonController);

PersonController.$inject = ['$scope', '$state', 'Api'];

function PersonController($scope, $state, Api) {

  $scope.getPersons = function() {
      Api.getPersons().then(function(response) {
             $scope.persons = response.data;
      }, function(error) {
          // error message
      });
  };
}

Persons.html

<div ng-controller="PersonController">
  <div id="grid1" ui-grid="{ data: persons }" class="grid"></div>
  <button ng-click="getPersons()"></button>
</div>

摘要

  1. 您的view显示$scope内的数据
  2. 该视图具有一个controller ,该controller仅用于获取数据并将其存储在$scope ,为按钮提供功能
  3. 您的services正在将数据传递到控制器

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM