正确处理角度

时间:2016-09-04 10:06:56

标签: javascript angularjs

我试图了解如何正确处理Angular 1中的数据。

我正在使用基于组件的方法。让我们考虑一个简单的案例。我有侧导航和仪表板。我需要在这些组件中显示部门数据。

import sidenavHtml from './sidenavigation.html';
import sideNavController from './sidenavigation.controller';

export default SideNavigation;

SideNavigation.$inject = [
];

function Sidenav() {
    return {
        restrict: 'E',
        scope: {},
        template: sidenavHtml,
        controller: sideNavController,
        controllerAs: 'ctrl',
        link: function ($scope, elem, attrs) {

        }
    };
}

export default class SideNavigationController {
    ...

    $onInit() {
        this.getDepartments();
    }

    getDepartments() {
        this.departmentService.getDepartments().then((result) => {
            this.departments= result.data;
        });
    }
}

export default class DashboardController {
    ...

    $onInit() {
        this.getDepartments();  
    }

    getDepartments() {

        this.departmentService.getDepartments().then((result) => {
            this.departments= result.data;              
        });
    }
}

export default Departments;  

function Departments($http) {

    function getDepartments() {
        return $http({url: 'http://localhost:9000/api/departments', method: 'GET'});
    }

     function create(newDepartment) {
        return $http.post('http://localhost:9000/api/departments', newDepartment);
    }

    return {getDepartments, create};
}

Dashboard组件中,用户可以创建新部门(创建是从Dashboard组件调用的另一个组件)。当用户创建新部门时,我需要通知SideNavigationDashboard。因此,在DashboardSideNavigation组件中,我使用以下代码: this.$rootScope.$on('updateDepartmens', ()=> { this.getDepartments(); });

嗯,这种方法的缺点是显而易见的。当我的应用程序呈现时,我得到两个http请求,我使用$rootScope。我决定以下列方式重写服务:

export default Departments;  

    function Departments($http) {
        this.departments;

        function getDepartments() {
           if(!departments) {
             $http({url: 'http://localhost:9000/api/departments', method: 'GET'})
             .then((response) => {                   
                this.departments = response.data;                    
             })
             .catch((err) => {
                console.log('error');   
             });
           }

           return this.departments; 
        }

         function create(newDepartment) {
            $http.post('http://localhost:9000/api/departments', newDepartment)
            .then((response) => {
               // handle response and add to departments;
               ...
               this.departments.push(response.data);
            );
    }  

        return {getDepartments, create};
    }

您认为这是一种好方法还是另一种方式?

当我不需要共享数据并在需要共享数据时使用第二种方法(绑定到变量)时,您认为我应该如何整体使用此方法或使用我的第一种方法(发出http请求的调用服务方法)?

另外一个问题。您是否将映射服务器模型用于客户端模型或仅使用从服务器返回的对象?

1 个答案:

答案 0 :(得分:1)

您认为这是一种好方法还是另一种方式?

我认为您的第二种方法是正确的,但是,如果您想拦截某个事件,例如,在获取数据时重新加载数据,您不希望每次都自动执行绑定到该事件的特定函数。

我最近遇到了类似的问题,我只有在factory提取数据时才需要执行函数。我讨厌使用$rootScope来做这些事情。我不喜欢使用它,因为它使应用程序混乱,我也注意到应用程序基准测试的副作用。但正如您所知,使用$rootScope$broadcast之类的$on事件确实是一件好事。

我发现了一种更好的方法来实现这样的事情。使用Postal.js,您可以在应用程序上创建所需组件之间共享的虚拟总线。例如,您可以使用reloadItemsDataFactory订阅频道DataController,并且只会在该频道上发出您提取的项目并拦截控制器上的消息并执行绑定到该事件的函数。之后,如果您愿意,您可以取消订阅该频道并免费使用该巴士。您可以使用n个不同的模块共享特定总线。

我注意到使用此库可以提高应用程序的整体速度,因为我没有附加任何内容$rootScope

这是一个使用示例

// . . . Cool stuff
//Factory
$scope.$bus.publish({
                  channel : 'reloadItems',
                  topic   : 'reloadItems'
                  data    : items
);

// . . . Cool Stuff also
//Controller
$scope.$bus.subscribe({
  channel  : 'reloadItems',
  topic    : 'reloadItems',
  callback : function () {
    reloadItems();
  }
});

我真的建议你试一试。你可以找到一篇关于如何将它与Angular here一起使用的有趣文章。

当我不需要共享数据并在需要时使用第二种方法(绑定到变量)时,您认为我应该如何整体使用此方法或使用我的第一种方法(发出http请求的调用服务方法)分享数据?

我觉得你不应该把这些东西绑定到变量上。只需使用事件来管理它。而且,正如我之前所说,你的第二种方法更好,更模块化。

您是否将映射服务器模型用于客户端模型或仅使用从服务器返回的对象?

就个人而言,我只使用从服务器返回的对象。我喜欢有一个纤薄的前端,我充分利用后端数据的解析,但是,如果我不知何故需要在前端处理数据,我从不在控制器中做到这一点,我在工厂或服务。

我希望我能提供帮助。