将DOM操作与Angular控制器分开 - 需要最佳实践

时间:2015-03-11 13:57:34

标签: javascript angularjs angularjs-directive

试图找到最好的"构建Angular应用程序的方法我发现了几篇最佳实践文章。有了这个输入,我就这样做了:

angular.module('xApp', [])
//..... some services, factories, controllers, ....

.directive('dirNotification',[ function dirNotification() {
    return {
        scope: {}, 
        templateUrl: 'xNotification.html',
        replace: true,
        controller: 'CtrlNotification',
        link: function($scope){
            // if this is 'DOM manipulation, should be done here ... ?
            /*
            $scope.$on('session.update',function(event, args) {
                if (args == null) {
                    $scope.notificationdata.username = "";
                    $scope.notificationdata.sid = "";
                } else {
                    $scope.notificationdata.username = args.username;
                    $scope.notificationdata.sid = args.accessToken;
                }
            });
            */
        }

    };
}])
.controller('CtrlNotification',['$scope' ,function CtrlNotification($scope) {

    $scope.notificationdata = {
        username: "",
        sid: ""
    };

    // this is not real DOM manipulation, but only view data manipulation?
    $scope.$on('session.update',function(event, args) {
        if (args == null) {
            $scope.notificationdata.username = "";
            $scope.notificationdata.sid = "";
        } else {
            $scope.notificationdata.username = args.username;
            $scope.notificationdata.sid = args.accessToken;
        }
    });

}])

HTML模板就是这样:

<div>
    <p>{{notificationdata.username}}</p>
    <p>{{notificationdata.sid}}</p>
</div>

所以我的问题是,数据更改是否应被视为DOM操作?在控制器中执行此操作的当前版本对我来说似乎更实用(例如,设置默认值)。此外,如果我添加更多功能,&#34;指令链接&#34;块将增长并包含比定义更多的功能。我想在指令中应根据范围数据改变颜色或隐藏元素等事情。

社区是什么意思?你同意我的假设吗?

谢谢, 赖

1 个答案:

答案 0 :(得分:8)

作为一个良好的开端,请阅读此SO question/answer

控制器:

你不应该在控制器中进行DOM操作(或查找DOM元素,或对视图做出任何假设)的原因是因为控制器的意图只是处理控制器的状态。 app - 通过更改ViewModel - 无论状态如何在View中反映出来。此控制器通过响应模型中的事件以及ViewModel的View和设置属性来实现此目的。 Angular将处理使用绑定反映视图中App的“状态”。

所以,是的,当然,更改ViewModel会导致View做出反应并操纵DOM,但想法是控制器不应该知道或关心View的反应。这使问题的分离保持不变。

<强>指令:

如果内置指令不够,并且您需要更严格地控​​制 视图的反应方式,那么这是创建自定义指令的一个很好的理由。

有关指令的两件事要记住。

1)将指令视为可重用组件很有用,因此特定于应用程序的逻辑越少越好。当然,避免任何业务逻辑。定义输入和输出(通常通过属性)并仅对那些做出反应。事件监听器(与您一样)是非常特定于应用程序的(除非该指令旨在与另一个发布事件的指令一起使用),因此如果可能的话,最好避免使用。

.directive("notification", function(){
  return {
    restrict: "A",
    scope: {
      notification: "=" // let the attribute get the data for notification, rather than
                        // use scope.$on listener
    },
    // ...
  }
})

2)仅仅因为指令“允许进行DOM操作”并不意味着您应该忘记ViewModel-View分离。 Angular允许您在链接或控制器函数内定义范围,并提供包含所有典型Angular表达式和绑定的模板。

template: '<div ng-show="showNotification">username:{{notification.username}}</div>',

// controller could also have been used here
link: function(scope, element, attrs){ 
   scope.showNotification = Math.floor(Math.random()* 2);    
}
相关问题