TL; DR 我解决了我的问题。这里有三种不同的解决方案:
http://plnkr.co/edit/E0ErKs?p=preview
我不喜欢slider1,因为它在$ scope({{sliderValue}})中存储了值,并且根据Angular Style Guide的推荐,我们应该避免这种情况。
我不喜欢slider2,因为它假定controler在视图中有别名vm(所以我们在视图和指令之间创建某种耦合)。
解决方案3对我来说很合适。我错过了什么吗?
你如何以不同的方式写出这个指令以符合Angular哲学?
初步问题:
我正在学习角度,但对我来说并非一切都很清楚。
我发现了这个问题: How to use jQuery in AngularJS
所以我创建了工作示例:
指令:
(function() {
'use strict';
angular.module('demoApp').directive('slider', function () {
return {
restrict: 'A',
controller: function ($scope, $element, $attrs) {
$scope.onSlide = function (e, ui) {
$scope.sliderValue = ui.value;
$scope.$digest();
};
},
link: function (scope, el, attrs) {
var options = {
value: scope.sliderValue,
slide: scope.onSlide
};
// set up slider on load
angular.element(document).ready(function () {
scope.$slider = $(el).slider(options);
});
}
}
});
})();
控制器:
(function() {
'use strict';
angular.module('demoApp').controller('DemoAppTestCtrl', DemoAppTestCtrl);
DemoAppTestCtrl.$inject = [ '$scope' ];
function DemoAppTestCtrl($scope) {
$scope.sliderValue = 10;
}
})();
和Html页面:
<div ng-controller="DemoAppTestCtrl as vm">
Value: {{sliderValue}}
<div slider></div>
</div>
一切正常。 Angular put滑块代替&lt; div slider&gt;我可以移动它,我会在{{sliderValue}}中看到更改值。
然后我找到了这个角度风格指南 https://github.com/johnpapa/angular-styleguide
在关于控制器的章节中,他们建议使用带有vm语法的controllerAs(因为$ scope是坏的或者是什么)。
例如:
function CustomerController() {
var vm = this;
vm.name = {};
vm.sendMessage = function() { };
}
所以我把控制器改成了这个:
(function() {
'use strict';
angular.module('demoApp').controller('DemoAppTestCtrl', DemoAppTestCtrl);
DemoAppTestCtrl.$inject = [ ];
function DemoAppTestCtrl($scope) {
var vm = this;
vm.sliderValue = 10;
}
})();
和Html页面:
<div ng-controller="DemoAppTestCtrl as vm">
Value: {{vm.sliderValue}}
<div slider></div>
</div>
但我不知道如何解决我的指示。 我想要相同的功能,当我移动滑块时我想在控制器内设置vm.sliderValue而不是范围内的$ scope.sliderValue。
EDIT1:
我能够通过在控制器和链接函数中添加$ scope.vm来使其工作(因为我的控制器在作为vm的范围内)。但我不确定这是否是正确的方法,因为现在我的指令假设在$ scope.vm别名下有范围内的控制器。
这是不好的设计还是正常的Angular服务方式?
(function () {
'use strict';
angular
.module('demoApp')
.directive('slider', slider);
slider.$inject = [ ];
function slider() {
return {
restrict: 'A',
controller: function ($scope, $element, $attrs) {
$scope.vm.onSlide = function (e, ui) {
$scope.vm.sliderValue = ui.value;
$scope.$digest();
};
},
link: function (scope, el, attrs) {
var options = {
value: scope.vm.sliderValue,
slide: scope.vm.onSlide
};
// set up slider on load
angular.element(document).ready(function () {
scope.$slider = $(el).slider(options);
});
}
}
}
})();
EDIT2:
我能够创建具有3个不同版本的工作Plunker: http://plnkr.co/edit/E0ErKs?p=preview
答案 0 :(得分:0)
使用范围:false作为指令中的选项。
http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/
答案 1 :(得分:0)
尝试这样的事情:
angular.module('myApp', []);
angular.module('myApp').controller('DemoAppTestCtrl', DemoAppTestCtrl);
function DemoAppTestCtrl() {
var vm = this;
vm.sliderValue = 10;
}
angular.module('myApp').directive('slider', sliderDirective );
function sliderDirective() {
return {
restrict: 'A',
controller: sliderController,
controllerAs: 'sliderCtrl',
template: "<p>{{sliderCtrl.test}}</p>"
}
}
function sliderController() {
var vm = this;
vm.test = "hello";
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="DemoAppTestCtrl as vm">
Value: {{vm.sliderValue}}
<div slider></div>
</div>
</div>
&#13;