AngularJS - $emit/$on 或范围继承哪个更好? [英] AngularJS - Which is better, $emit/$on or scope inheritance?

查看:22
本文介绍了AngularJS - $emit/$on 或范围继承哪个更好?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我得到了以下 HTML 结构:

Say I got this following HTML structure:

<body ng-app="demo" ng-controller="RootCtrl">
    <header>
        <!-- Header Material -->
    </header>

    <main ng-controller="MainCtrl">
        <!-- Main Content -->

        <nav ng-controller="NavCtrl">
            <!-- Navbar -->
        </nav>
    </main>
<body>

现在,假设 NavCtrl 需要操作一个恰好存在于 RootCtrl 范围内的模型 - 在这种情况下 $emit/$on 更适合?以及在什么情况下通过作用域继承直接操作模型会更好?

Now, suppose NavCtrl needs to manipulate a model that happens to exist under RootCtrl's scope - under which conditions would $emit/$on be better suited? And under which conditions would it be better to directly manipulate the model via scope inheritance?

推荐答案

如果您使用原型继承,则需要小心,因为在父控制器和子控制器中使用相同的变量名称时很容易出错.这可以通过确保 $scope 变量在它们的某处有一个点"来避免,但需要纪律来确保你总是这样做.您还可以使用 $scope.$parent.$parent 结构访问在 RootCtrl 中设置的 NavCtrl 中的变量,但这很脆弱,并且本质上将您的控制器与 DOM 结构联系起来,这是解决问题的秘诀线.

If you're using prototypical inheritance, you need to be careful as it's easy to make errors when using same variable names in parent and child controllers. This can be avoided by making sure $scope variables always 'have a dot' in them somewhere, but needs discipline to make sure you always do this. You could also access a variable in NavCtrl set in RootCtrl using the $scope.$parent.$parent structure, but this is brittle and essentially ties your controllers to the DOM structure which is a recipe for problems down the line.

$emit/$on 有一个问题,如果您在事件名称中打错字,则可能会默默地失败,并且在发生错误时很难跟踪发生的事情.最好少用它们.http://eburley.github.io/2013/01/31/angularjs-watch-pub-sub-best-practices.html 说只在当你需要让多个订阅者知道一个事件并且这些订阅者需要做的不仅仅是向他们的视图传播信息时才使用它们."

$emit/$on have the issue of potentially silently failing if you make a typo in the name of the event, and can make it hard to follow what's happening in the event of an error. It's better to use them sparingly. http://eburley.github.io/2013/01/31/angularjs-watch-pub-sub-best-practices.html says only to use them "when you need to let multiple subscribers know about an event and those subscribers need to do more than radiate information to their view."

在控制器之间共享数据模型的正常 Angular 方法是创建一个服务,并将其注入到两个控制器中.这也符合 OOP 的优先组合胜于继承"原则.

The normal Angular way to share data models across controllers is to make a service, and inject that into both controllers instead. This fits with the "prefer composition over inheritance" principle of OOP in general too.

app.service('dayService', function () {      
    var day = 'Monday';
    return {
        getDay: function() {
           return day;
        },
        setDay: function(thisDay) {
           day = thisDay;
        }
    };
})

function NavCtrl($scope, dayService) {
    $scope.day = dayService.getDay();
}

function RootCtrl($scope, dayService) {
    dayService.setDay('Sunday');
}

HTML:

<nav ng-controller="NavCtrl">
    Today is {{day}}
</nav>

您可能还会发现 Misko 的关于 Angular 最佳实践的视频很有趣,它讨论了在控制器和服务大约 28 分钟标记,以及更多关于事件 ($emit/$on) 接近尾声.他的结论(释义)是,事件有点问题,最好仅用于两件事真的不需要相互了解并且必须保持非常分开的情况,或者如果事件并不总是必要的,有时可以忽略.

You might also find Misko's video on Angular best practices interesting, it talks about what to put in controllers vs services around the 28 min mark, and more about events ($emit/$on) towards the end. His conclusion (paraphrased) is that events are somewhat problematic best used only for situations where two things really don't need to know about each other and have to be kept very separate, or if the event is not always necessary can sometimes be ignored.

我想说的基本规则是:

  • 使用服务在两个控制器之间共享数据,它比继承稍微复杂一点,但也没什么难度.

  • Use service for sharing data between two controllers, it's slightly more complex than inheritance but nothing too difficult.

使用事件以复杂的方式在多个不同订阅者之间共享.

Use events for sharing between multiple different subscribers in complex ways.

控制器中的$scope 应该是只写"(规则直接取自上面 Misko 的最佳实践视频).NavCtrl 需要操作恰好存在于 RootCtrl 范围下的模型"的范围继承也将涉及读取父范围,所以我认为最好避免.

$scope in controllers should be 'write only' (rule taken directly from Misko's best practices video above). Scope inheritance where "NavCtrl needs to manipulate a model that happens to exist under RootCtrl's scope" would involve reading parent scope too, so I think is best avoided.

这篇关于AngularJS - $emit/$on 或范围继承哪个更好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆