简体   繁体   English

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

[英]Separating DOM manipulation from Angular controllers - Best Practice wanted

Trying to find the "best" way building an Angular App I found several best practice articles. 试图找到构建Angular App的“最佳”方法我找到了几篇最佳实践文章。 With this input I did this: 有了这个输入,我做了这个:

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;
        }
    });

}])

The HTML template is simply this: HTML模板就是这样的:

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

So my question is, should data changes to be considered as DOM manipulation? 所以我的问题是,数据更改是否应被视为DOM操作? The present version doing this within the controller seems more practical to me (eg setting default values). 在控制器中执行此操作的当前版本对我来说似乎更实用(例如,设置默认值)。 Also if I add more functionality to that, the "directive link" block will grow and contain more functions than definitions. 此外,如果我添加更多功能,“指令链接”块将增长并包含比定义更多的功能。 I guess within the directive things like changing colors or hiding elements depending on the scope data should be done there. 我想在指令中应该在那里根据范围数据更改颜色或隐藏元素。

What does the community mean? 社区是什么意思? Do you agree with my assumptions? 你同意我的假设吗?

Thanks, Rainer 谢谢,Rainer

As a good start, read this SO question/answer . 作为一个良好的开端,请阅读这个问题/答案

Controllers: 控制器:

The reason you shouldn't do DOM manipulation (or lookup of DOM elements, or making any assumptions about the View, for that matter) in the controller is because the intent of the controller is to deal only with the state of the app - by changing the ViewModel - irrespective of how the state is reflected in the View. 你不应该在控制器中进行DOM操作(或查找DOM元素,或对视图做出任何假设)的原因是因为控制器的意图只是处理应用程序的状态 - 通过更改ViewModel - 无论状态如何在View中反映出来。 This controller does that by reacting to events from the Model and from the View and setting properties of the ViewModel. 此控制器通过响应模型中的事件以及ViewModel的View和设置属性来实现此目的。 Angular will deal with reflecting the "state" of the App in the View with bindings. Angular将通过绑定来反映视图中应用程序的“状态”。

So, yes, of course, changing the ViewModel causes the View to react and DOM to be manipulated, but the idea is that the controller should not know or care about how exactly the View is reacting. 所以,是的,当然,更改ViewModel会导致View做出反应并操纵DOM,但想法是控制器不应该知道或关心View的反应。 This keeps the separation of concerns intact. 这使问题的分离保持完整。

Directives: 指令:

When built-in directives are not enough and you require tighter control about how the View is reacting, this is a good reason to create a custom directive. 当内置指令是不够的,你需要有关的看法是怎样的反应更严格的控制,这是一个很好的理由来创建自定义指令。

Two things to remember about directives. 关于指令要记住两件事。

1) It's useful to think of directives as re-usable components, so the less app-specific logic there is, the better. 1)将指令视为可重用的组件是有用的,因此特定于应用程序的逻辑越少越好。 And definitely, avoid any business logic there. 当然,避免任何业务逻辑。 Define inputs and outputs (typically via attributes) and react only to those. 定义输入和输出(通常通过属性)并仅对那些做出反应。 Event listeners (like you have) are very app-specific (unless this directive is intended to be used with another directive that publishes an event), so better be avoided, if possible. 事件监听器(与您一样)是非常特定于应用程序的(除非该指令旨在与另一个发布事件的指令一起使用),因此如果可能的话,最好避免使用。

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

2) Just because directives are "allowed to do DOM manipulations" doesn't mean that you should forget about the ViewModel-View separation. 2)仅仅因为指令“允许进行DOM操作”并不意味着你应该忘记ViewModel-View分离。 Angular allows you to define scope inside a link or a controller function, and provide a template with all the typical Angular expressions and bindings. 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);    
}

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

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