Bor*_*ris 2 javascript coding-style function hoisting angularjs
关于使用变量绑定与私有方法命名函数约定时构造Angular代码和JavaScript行为的一些问题.是否存在使用AngularJS中的变量绑定函数/第一类函数而不是私有方法命名的性能或风格原因?每种方法如何影响吊装?下面的第二种方法是否会减少提升量,这会对应用性能产生明显影响吗?
私有方法命名的示例.这是构建Angular代码的推荐方法吗?
(function () {
'use strict'
function modalController(dataItemsService, $scope) {
var vm = this;
function _getSelectedItems() {
return dataItemsService.SelectedItems();
}
function _deleteSelectedItems() {
dataItemService.DeleteItem();
$("#existConfirmDialog").modal('hide');
}
vm.SelectedItems = _getSelectedItems;
vm.deleteItemRecord = _deleteItemRecord;
}
angular.module('app').controller('modalController', ['dataItemService', '$scope', modalController]
})();
Run Code Online (Sandbox Code Playgroud)
变量绑定函数的示例.在控制器中构造角度代码的这种方法怎么样 - 在性能/风格方面有任何缺点或优势吗?
angular.module('appname').controller("NameCtrl", ["$scope", "$log", "$window", "$http", "$timeout", "SomeService",
function ($scope, $log, $window, $http, $timeout, TabService) {
//your controller code
$scope.tab = 0;
$scope.changeTab = function(newTab){
$scope.tab = newTab;
};
$scope.isActiveTab = function(tab){
return $scope.tab === tab;
};
}
]);
Run Code Online (Sandbox Code Playgroud)
使用"私有"方法并通过公共别名公开它们的第一种方法被称为显示模块模式,尽管在该示例中方法实际上不是私有的.
后者是一个非常标准的构造函数模式,使用$ scope作为上下文.
是否存在使用
variableAngularJS中的绑定函数/第一类函数而不是私有方法命名的性能或风格原因?是否[推荐]构建Angular代码的方法?
TL; DR
从根本上说,上述两种风格没有太大区别.一个使用$scope,另一个this.一个构造函数在闭包中定义,一个是内联定义的.
在某些情况下,您可能需要私有方法或值.使用变量this/ vmover 还有风格和(可能无关紧要)的性能原因$scope.这些不是相互排斥的.
你可能想要使用一个基本的,裸露的骨头,旧学校的构造函数模式,并且许多人通过this代替而暴露状态和行为$scope.
您可以在Controller中允许自己的数据隐私,但大多数情况下,这应该由服务/工厂利用.主要的例外是代表View状态的数据.
请不要在Controller中使用jQuery.
参考文献:
Todd Motto的AngularJS风格指南.
为了彻底回答您的问题,我认为理解财务主任的责任非常重要.每个控制器的工作都是向View公开一组严格的状态和行为.简而言之,只能在您的视图中分配this或$scope不想让用户看到或玩的东西.
的variable问题(vm,$scope)是上下文(this由控制器功能正在创建的实例).
$scope是Angular的"特殊"背景; 它已经为你定义了一些行为(例如$ scope.$ watch).$scopes也遵循继承链,即$ scope继承分配给其父$ scope的状态和行为.
拿这两个控制器:
angular.module("Module")
.controller("Controller", ["$scope", function($scope) {
$scope.tab = 0;
$scope.incrementTab = function() {
$scope.tab++;
};
}])
.controller("OtherController", ["$scope", function($scope) {
// nothing
}]);
Run Code Online (Sandbox Code Playgroud)
一个观点
<div ng-controller="Controller">
<p>{{ tab }}</p>
<button ng-click="incrementTab();">Increment</button>
<div ng-controller="OtherController">
<p>{{ tab }}</p>
<button ng-click="incrementTab();">Increment</button>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
这里的例子
您会注意到,即使我们没有$scope.tab在OtherController中定义,它也会从Controller继承它,因为Controller是它在DOM中的父级.在显示选项卡的两个位置,您应该看到"0".这可能是你所指的"吊装",尽管这是一个完全不同的概念.
点击第一个按钮会发生什么?在这两个地方,我们都暴露了"标签",它们现在将显示"1".当您按下第二个按钮时,两者都会更新和增加.
当然,我可能不希望我的子标签与父标签具有相同的标签值.如果您将OtherController更改为:
.controller("OtherController", ["$scope", function($scope) {
$scope.tab = 42;
}]);
Run Code Online (Sandbox Code Playgroud)
您会注意到此行为已更改 - 选项卡的值不再同步.
但现在令人困惑:我有两个叫做"tab"的东西是不一样的.其他人可能会使用"tab"在线下编写一些代码并无意中破坏我的代码.
我们过去通过使用命名空间来解决这个问题$scope,例如$scope.vm并将所有内容分配给命名空间:$scope.vm.tab = 0;
<div ng-controller="OtherController">
<p>{{ vm.tab }}</p>
<button ng-click="vm.incrementTab();">Increment</button>
</div>
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用简单和简洁,this并利用controllerAs语法.
.controller("OtherController", function() {
this.tab = 0;
});
<div ng-controller="OtherController as oc">
<p>{{ oc.tab }}</p>
</div>
Run Code Online (Sandbox Code Playgroud)
对于习惯使用普通JS的人来说,这可能会更舒服,并且通过这种方式避免与其他Angular源冲突也更容易.您可以随时更改命名空间.由于你没有创建一个新的$scope实例,它的性能也有点"轻" ,但我不确定它有多大的收益.
为了实现隐私,我建议将数据封装在服务或工厂中.记住,控制者并不总是单身; View和Controller之间存在1:1的关系,您可以多次实例化同一个控制器!但是,工厂和服务对象是单身人士.他们非常擅长存储共享数据.
让所有控制器从单例中获取状态的副本,并确保所有控制器都使用在服务/工厂上定义的行为来修改单例状态.
function modalController(dataItemsService) {
var vm = this;
vm.selectedItems = dataItemsService.SelectedItems(); // get a copy of my data
vm.updateItem = dataItemService.UpdateItem; // update the source
}
Run Code Online (Sandbox Code Playgroud)
但是等一下,我怎么知道我的应用程序的另一部分何时更改了我的私人数据?我如何知道何时获取SelectedItems的新副本?这是$ scope.$ watch发挥作用的地方:
function modalController(dataItemsService, $scope) {
var vm = this;
vm.updateItem = dataItemService.UpdateItem; // update the source
// periodically check the selectedItems and get a fresh copy.
$scope.$watch(dataItemsService.SelectedItems, function(items) {
vm.items = items;
});
// thanks $scope!
}
Run Code Online (Sandbox Code Playgroud)
如果您的数据未共享,或者您的私有数据代表View层而不是Model层,那么将它保存在控制器中是完全可以的.
function Controller() {
var buttonClicked = false;
this.click = function() {
buttonClicked = true; // User can not lie and say they didn't.
};
}
Run Code Online (Sandbox Code Playgroud)
最后,不要像你的参考那样在你的控制器中使用JQUERY!
$("#existConfirmDialog").modal('hide');
Run Code Online (Sandbox Code Playgroud)
这个例子可能不是纯粹的邪恶,但是避免在指令之外访问和修改DOM,你不想通过修改它下面的DOM来破坏应用程序的其他部分.