关于使用变量绑定与私有方法命名函数约定时构造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]
})();
变量绑定函数的示例。在控制器中构造角度代码的这种方法怎么样?在性能/风格方面有任何缺点或优势吗?
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;
};
}
]);
答案 0 :(得分:5)
第一种方法,使用" private"方法和通过公共别名公开它们被称为Revealing Module Pattern,尽管在这个例子中这些方法实际上并不是私有的。
后者是一个非常标准的Constructor Pattern,使用$ scope作为上下文。
在AngularJS中使用
variable
绑定函数/第一类函数是否存在性能或风格上的原因而不是私有方法命名?是否有[推荐]构建Angular代码的方法?
TL; DR
从根本上说,两种风格之间没有太大区别
以上。一个使用$scope
,另一个使用this
。一个构造函数在闭包中定义,一个是内联定义的。
在某些情况下,您可能需要私有方法或值。
还有风格和(可能微不足道)的表现
使用变量this
/ vm
而不是$scope
的原因。这些不是相互排斥的。
您可能想要使用
基本的,裸露的骨头,旧学校的构造函数模式,以及很多
人们通过this
代替$scope
来揭露状态和行为。
您可以在Controller中自行保护数据隐私,但大部分都是如此 服务/工厂应该利用这个时间。主要的例外是代表View状态的数据。
请不要在您的控制器中使用jQuery。
参考文献:
Todd Motto要彻底回答您的问题,我认为理解财务主任的责任非常重要。每个控制器的工作都是向View公开一组严格的状态和行为。简而言之,只需将{* 1}}或this
分配给用户在视图中看到或玩的内容。
有问题的$scope
(variable
,vm
)是Controller函数创建的实例的上下文($scope
)。
this
是Angular"特别"上下文;它已经为你定义了一些行为(例如$ scope。$ watch)。 $scope
也遵循继承链,即$ scope继承分配给其父$ scope的状态和行为。
拿这两个控制器:
$scopes
和视图
angular.module("Module")
.controller("Controller", ["$scope", function($scope) {
$scope.tab = 0;
$scope.incrementTab = function() {
$scope.tab++;
};
}])
.controller("OtherController", ["$scope", function($scope) {
// nothing
}]);
示例here
你注意到的是,即使我们没有在OtherController中定义<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>
,它也会从Controller继承它,因为Controller是它在DOM中的父级。在显示选项卡的两个位置,您应该看到&#34; 0&#34;。这可能是您所指的"hoisting",尽管这是一个完全不同的概念。
点击第一个按钮后会发生什么?在这两个地方,我们已经曝光了#34; tab&#34;,他们现在将显示&#34; 1&#34;。当您按下第二个按钮时,两者也会更新和增加。
当然,我可能不希望我的子标签与父标签的标签值相同。如果您将OtherController更改为:
$scope.tab
您会注意到此行为已更改 - 标签的值不再同步。
但是现在它令人困惑:我有两个叫做#34; tab&#34;不是一样的。其他人可能会在以后使用&#34; tab&#34;写下一些代码。并且无意中破坏了我的代码。
我们过去通过在.controller("OtherController", ["$scope", function($scope) {
$scope.tab = 42;
}]);
上使用命名空间来解决此问题。 $scope
并将所有内容分配给命名空间:$scope.vm
$scope.vm.tab = 0;
另一种方法是使用<div ng-controller="OtherController">
<p>{{ vm.tab }}</p>
<button ng-click="vm.incrementTab();">Increment</button>
</div>
的简单性和简洁性,并利用controllerAs语法。
this
对于习惯使用普通JS的人来说,这可能会更舒服,并且通过这种方式更容易避免与其他Angular源的冲突。您可以随时更改命名空间。它也有点“轻”&#34;因为您没有创建新的.controller("OtherController", function() {
this.tab = 0;
});
<div ng-controller="OtherController as oc">
<p>{{ oc.tab }}</p>
</div>
个实例,但我不确定是否有很多收获。
为了实现隐私,我建议将数据封装在服务或工厂中。记住,控制者并不总是单身; View和Controller之间存在1:1的关系,您可以多次实例化同一个控制器!但是,工厂和服务对象是单身人士。他们非常擅长存储共享数据。
让所有控制器从单例中获取状态的副本,并确保所有控制器都使用在服务/工厂上定义的行为来修改单例状态。
$scope
但是等等,我怎么知道我的应用程序的另一部分何时更改了我的私人数据?我如何知道何时获取SelectedItems的新副本?这是$ scope。$ watch发挥作用的地方:
function modalController(dataItemsService) {
var vm = this;
vm.selectedItems = dataItemsService.SelectedItems(); // get a copy of my data
vm.updateItem = dataItemService.UpdateItem; // update the source
}
如果您的数据未被共享,或者您的私人数据代表的是View图层而不是Model图层,那么将它保存在控制器中是完全可以的。
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!
}
最后,不要像你的参考那样在你的控制器中使用JQUERY!
function Controller() {
var buttonClicked = false;
this.click = function() {
buttonClicked = true; // User can not lie and say they didn't.
};
}
这个例子可能不是纯粹的邪恶,但是避免在指令之外访问和修改DOM,你不想通过修改它下面的DOM来打破你应用程序的其他部分。