我有多个angularJS指令(使用其中一个有角度的chart.js版本)
现在我需要在这些指令中使用一些函数。
让我不重复自己的好方法是什么,所以从指令中删除代码并将其放在一个地方。因为该代码无论如何都是相同的。 我已经研究了范围的继承,但还没有能够解决这个问题。
这是多个指令中使用的代码:
$scope.widgetData = false;
$scope.graphData = false;
$scope.graphSelectorIndex = 0;
$scope.graphSelector = [
{ 'byPeriod' : 'Periode'},
{ 'byHour' : 'Uur' },
{ 'byDay' : 'Dag'}
];
$scope.graphSelectorByText = function (text) {
switch (text) {
case ('byPeriod'):
$scope.selector = 'byPeriod'
$scope.graphData = $scope.allGraphData.byPeriod;
$scope.graphType = 'Line';
break;
case ('byDay'):
$scope.selector = 'byDay'
$scope.graphData = $scope.allGraphData.byDay;
$scope.graphType = 'Line';
break;
case ('byHour'):
$scope.selector = 'byHour'
$scope.graphData = $scope.allGraphData.byHour;
$scope.graphType = 'Bar';
break;
}
}
$scope.graphSelectorByInt = function (int) {
switch (int) {
case (0):
$scope.selector = 'byPeriod';
$scope.graphData = $scope.allGraphData.byPeriod;
$scope.graphType = 'Line';
break;
case (1):
$scope.selector = 'byDay';
$scope.graphData = $scope.allGraphData.byDay;
$scope.graphType = 'Line';
break;
case (2):
$scope.selector = 'byHour';
$scope.graphData = $scope.allGraphData.byHour;
$scope.graphType = 'Bar'
break;
}
}
$scope.graphSelectorPrev = function () {
$scope.graphSelectorIndex--;
if ($scope.graphSelectorIndex < 0) {
$scope.graphSelectorIndex = $scope.graphSelector.length-1;
}
$scope.graphSelectorByInt($scope.graphSelectorIndex);
console.log($scope.graphSelectorIndex);
}
$scope.graphSelectorNext = function () {
$scope.graphSelectorIndex++;
if ($scope.graphSelectorIndex >= $scope.graphSelector.length) {
$scope.graphSelectorIndex = 0;
}
$scope.graphSelectorByInt($scope.graphSelectorIndex);
console.log($scope.graphSelectorIndex);
}
一些html:
<div class="controls">
<span class="btn_arrow previous inactive" ng-click="graphSelectorPrev()">Vorige</span>
<p>{+ selector +}</p>
<span class="btn_arrow next" ng-click="graphSelectorNext()">Volgende</span>
</div>
感谢任何可以提供帮助的人!
答案 0 :(得分:1)
首先,在这种情况下,你可以这样做一些干:
HTML:
<div class="controlls"> <span class="btn_arrow previous inactive" ng-click="graphSelectorInc(-1)">Vorige</span>
<p>{{ selector }}</p> <span class="btn_arrow next" ng-click="graphSelectorInc(+1)">Volgende</span>
</div>
JS:
//Warning this approach is so called not monomorh(polymorph): the parameter of function is not strictly typed, so it lacks browser optimizations but in this case its not so important because code won't run often
$scope.graphSelectorByAny = function (step) {
switch (step) {
case ('byPeriod'):
case (0):
$scope.selector = 'byPeriod'
$scope.graphData = $scope.allGraphData.byPeriod;
$scope.graphType = 'Line';
break;
case ('byDay'):
case (1):
$scope.selector = 'byDay'
$scope.graphData = $scope.allGraphData.byDay;
$scope.graphType = 'Line';
break;
case ('byHour'):
case (2):
$scope.selector = 'byHour'
$scope.graphData = $scope.allGraphData.byHour;
$scope.graphType = 'Bar';
break;
}
}
$scope.graphSelectorInc = function (inc) {
$scope.graphSelectorIndex += inc;
if ($scope.graphSelectorIndex < 0) {
$scope.graphSelectorIndex = $scope.graphSelector.length - 1;
} else if ($scope.graphSelectorIndex >= $scope.graphSelector.length) {
$scope.graphSelectorIndex = 0;
}
$scope.graphSelectorByAny($scope.graphSelectorIndex);
console.log($scope.graphSelectorIndex);
}
我为你做了JSFiddle。
但是有一个单独的指示也很好,我不能写,因为我不知道你想要在控制器中想要什么数据。 Yo可以阅读指令和数据绑定from the official docs。
另外考虑使用services你希望乘法控制器/指令做同样的事情。
希望它会对你有所帮助。
答案 1 :(得分:1)
如果不知道指令之间的确切差异(也许你甚至不需要多个)我会建议使用服务或者只是创建一个控制器并将其添加到指令模板。
如果您获得了在指令之间共享状态的一些好处,我只会选择服务,否则我会选择控制器。
以下是我使用控制器&#39; (在jsfiddle上测试):
angular.module('myApp', [])
.controller('sharedCtrl', function() {
var self = this;
// $scope.doIt = ...
self.doIt = function (msg) {
alert(msg);
};
})
.directive('dir1', function () {
return {
restrict: 'E',
template: '<div ng-controller="sharedCtrl as ctrl"><button ng-click="ctrl.doIt(msg)">dir1</button></div>',
scope: {},
link: function (scope) {
scope.msg = 'Hi, I\'m dir1!';
}
};
})
.directive('dir2', function () {
return {
restrict: 'E',
template: '<div ng-controller="sharedCtrl as ctrl"><button ng-click="ctrl.doIt(msg)">dir2</button></div>',
scope: {},
link: function (scope) {
scope.msg = 'Hi, I\'m dir2!';
}
};
});
如果需要从指令范围传递内容,可以将其简单地传递给控制器函数。
P.S。:我更喜欢controller as
语法而不是$scope
。如果您不熟悉它,可以将self
替换为$scope
,但我建议您进一步了解controller as
。
答案 2 :(得分:0)
我个人喜欢服务方式。
请参阅:http://jsfiddle.net/elennaro/b48jex3w/33/
以下是代码:
HTML
<div ng-controller="BaseCtrl">
<div class="controlls"> <span class="btn_arrow previous inactive" ng-click="graphSelectorInc(-1)">Vorige</span>
<p>{{ selector }}</p> <span class="btn_arrow next" ng-click="graphSelectorInc(+1)">Volgende</span>
</div>
JS
angular.module('myApp', [])
.service('GraphSelector', function () {
var graphSelectorIndex = 0;
var graphSelector = [{
'byPeriod': 'Periode'
}, {
'byHour': 'Uur'
}, {
'byDay': 'Dag'
}];
return {
selector: this.selector,
inc: function (inc) {
graphSelectorIndex += inc;
if (graphSelectorIndex < 0) {
graphSelectorIndex = graphSelector.length - 1;
} else if (graphSelectorIndex >= graphSelector.length) {
graphSelectorIndex = 0;
}
console.log(Object.keys(graphSelector[graphSelectorIndex]));
return graphSelector[graphSelectorIndex][Object.keys(graphSelector[graphSelectorIndex])[0]];
}
}
}).controller('BaseCtrl', function ($scope, GraphSelector) {
$scope.graphSelectorInc = function (inc) {
$scope.selector = GraphSelector.inc(inc);
}});
你看我有一个服务GraphSelector是一个单例,它存储graphSelectorIndex和graphSelector对于所有将给他打电话的所有控制器/指令都是一样的。
因此,您可以从任何想要切换当前选择器属性的地方调用此服务。
我使用Object.keys只获取返回给控制器的当前选择器状态的值。但是如果你想要,你可以返回整个对象并获得控制器中的值。
Angular JS服务是一个强大的工具,可以获得干净且可读的代码,我经常使用它来在控制器之间共享一些数据。
答案 3 :(得分:0)
您可以创建一个包含可重用逻辑的共享控制器,然后将其动态链接到您的指令。
所以你的控制器将是:
app.controller('sharedCtrl', function($scope) {
$scope.widgetData = false;
$scope.graphData = false;
$scope.graphSelectorIndex = 0;
$scope.graphSelector = [
{ 'byPeriod' : 'Periode'},
{ 'byHour' : 'Uur' },
{ 'byDay' : 'Dag'}
];
$scope.graphSelectorByText = function (text) {
switch (text) {
case ('byPeriod'):
$scope.selector = 'byPeriod'
$scope.graphData = $scope.allGraphData.byPeriod;
$scope.graphType = 'Line';
break;
case ('byDay'):
$scope.selector = 'byDay'
$scope.graphData = $scope.allGraphData.byDay;
$scope.graphType = 'Line';
break;
case ('byHour'):
$scope.selector = 'byHour'
$scope.graphData = $scope.allGraphData.byHour;
$scope.graphType = 'Bar';
break;
}
}
$scope.graphSelectorByInt = function (int) {
switch (int) {
case (0):
$scope.selector = 'byPeriod';
$scope.graphData = $scope.allGraphData.byPeriod;
$scope.graphType = 'Line';
break;
case (1):
$scope.selector = 'byDay';
$scope.graphData = $scope.allGraphData.byDay;
$scope.graphType = 'Line';
break;
case (2):
$scope.selector = 'byHour';
$scope.graphData = $scope.allGraphData.byHour;
$scope.graphType = 'Bar'
break;
}
}
$scope.graphSelectorPrev = function () {
$scope.graphSelectorIndex--;
if ($scope.graphSelectorIndex < 0) {
$scope.graphSelectorIndex = $scope.graphSelector.length-1;
}
$scope.graphSelectorByInt($scope.graphSelectorIndex);
console.log($scope.graphSelectorIndex);
}
$scope.graphSelectorNext = function () {
$scope.graphSelectorIndex++;
if ($scope.graphSelectorIndex >= $scope.graphSelector.length) {
$scope.graphSelectorIndex = 0;
}
$scope.graphSelectorByInt($scope.graphSelectorIndex);
console.log($scope.graphSelectorIndex);
}
});
你的指令看起来像这样:
app.directive('myDirective', function() {
return {
restrict: 'E',
controller: '@',
name: 'myDirectiveCtrl',
link: function($scope, $element, $attrs) {
// add directive specific logic
}
}
});
然后标记看起来像这样:
<my-directive my-directive-ctrl="sharedCtrl"></my-directive>