из $Scope в функцию
Изучаю Angular.
Я только делаю первые шаги, и сейчас делаю небольшое приложение, но дело в том что на многих страницах есть одинаковые $scope и соответственные функции. Пример
$scope.items = Users.query(function(data){
$scope.paginator.setPages($scope.items.length);
var i = 0;
angular.forEach(data, function(v,k) {
data[k]._id = i++;
});
});
или
$scope.sortBy = function() {
var order = [];
angular.forEach($scope.tablehead, function(h){
if (h.sort>0) order[h.sort-1] = h.name;
if (h.sort<0) order[Math.abs(h.sort)-1] = '-'+h.name;
});
return order;
};
Но дубляж кода не есть хорошо, решил уменьшить код, сделать функции из этих скопов, но ни в какую, только ошибки в консоли в формате что не может вызвать $scope из функции пишет что "TypeError: Cannot call method 'slice' of undefined..." slice это метод, он есть если вызывать $scope из примеров внутри контроллера... Подскажите как можно сделать из Скопа - функцию чтобы внутри нее можно было вызывать другие Скопы и с ними работать. |
Для начала, в angular есть встроенный сортировщик - orderBy.
А насчет ошибки, расскажите, пожалуйста, как вы вызываете функцию и саму эту функцию. |
Контроллер страницы
function sortReorder(col,e,scope) {
if (e.shiftKey) {
var sortIndex = 0;
angular.forEach(scope, function(el) {
if (Math.abs(el.sort)>sortIndex) sortIndex = Math.abs(el.sort);
});
angular.forEach(scope, function(el) {
if (el.name==col) el.sort = el.sort?-el.sort:sortIndex+1;
});
} else {
angular.forEach(scope, function(el) {
if (el.name==col) el.sort = el.sort>0?-1:1; else el.sort = null;
});
}
};
function UsersCtrl($scope, $routeParams, $location, Users) {
$scope.items = Users.query(function(data){
$scope.paginator.setPages($scope.items.length);
var i = 0;
angular.forEach(data, function(v,k) {
data[k]._id = i++;
});
});
$scope.selected = [];
$scope.paginator = {
count: 20,
page: 1,
pages: 1,
setPages: function(itemsCount){ this.pages = Math.ceil(itemsCount/this.count); }
};
$scope.sortBy = function() {
var order = [];
angular.forEach($scope.tablehead, function(h){
if (h.sort>0) order[h.sort-1] = h.name;
if (h.sort<0) order[Math.abs(h.sort)-1] = '-'+h.name;
});
return order;
};
$scope.sortReorder = function(col,e) { sortReorder(col,e,$scope.tablehead); };
}
Обратите внимание на sortReorder, это удалось превратить в функцию... и вызывать ее в разных контроллерах... А вот из вот этого
$scope.sortBy = function() {
var order = [];
angular.forEach($scope.tablehead, function(h){
if (h.sort>0) order[h.sort-1] = h.name;
if (h.sort<0) order[Math.abs(h.sort)-1] = '-'+h.name;
});
return order;
};
не получается, и вот из этого в особенности хочется, так как это то что может правильно перегрузить содержимое таблицы на странице
$scope.items = Users.query(function(data){
$scope.paginator.setPages($scope.items.length);
var i = 0;
angular.forEach(data, function(v,k) {
data[k]._id = i++;
});
});
Оба кода уникальны для всех страниц, сейчас у меня их уже 8... и в каждом контроллере страницы есть одинаковые куски кода... Я понимаю что может я говорю как Ламер... но я очень хочу разобраться... |
я правильно понял, что вы хотите вызвать sortReorder в функции $scope.sortBy?
|
Кажется, что-то тут не так... $scope только для чтения в шаблонах и только для записи в контроллере. Вы же в своих функциях используете область видимости для получения данных. Тогда уж нужно присвоить модель переменной и работать уже с ней.
var model = Users.query(function(data){
$scope.items = model
Возможно, имеет смысл создать собственный фильтр и использовать его в контроллере с помощью сервиса $filter |
Еще перевел статью по областям видимости: http://www.angular.ru/guide/understanding_scopes. Там как раз говорится о том, как пользоваться областями
|
Не знаю правильно ли я понял вопрос
Но если у тебя есть общие куски кода в нескольких контролёрах тогда создайте собственный модуль с нужными методами и подключайте его в тех контролёрах где он вам необходим. Это обыкновенное модульное программирование. вот кстатии хороший пример. http://www.angular.ru/guide/dev_guid...ng_controllers Сервис предоставляющий множество методов можно как нибудь так описать
angular.module('MyServiceModule', []).
factory('notify', function() {
return {
fync1:function(){},
fync2:function(){},
fync3:function(){}
}
});
либо
angular.module('MyServiceModule', []).
factory('notify', function() {
var f=function(){
//бла бла
},
p=f.prototype;
p.func1=function(){};
p.func2=function(){};
return new f();
//return f; если хочешь сам вызывать конструктор из контрола
});
3) Можно создать сервис users который будет возвращать не только данные но и методы работы с ними.(вероятно идеальное решение) 4) Придумал ещё один ход подобный примесям. Но сам бы я его пожалуй избегал до последнего.
angular.
module('MyServiceModule', []).
factory('extendScope',function() {
return function(scope) {
scope.fn1=function(){};
scope.fn2=function(){};
scope.fn3=function(){};
return scope;
}
});
function myController(scope, extendScope) {
extendScope(scope);
// или scope=extendScope(scope);
}
|
Спасибо большое за советы, наверное мне не хватает банальных знаний об Объектах.
Можно еще один вопрос:
<div class="span6" ng-controller="MyCtrl14">
MyCtrl14 > block14 =
<br>
<button ng-click="aMyCtrl14()">- ! -</button>
<br>
{{block14}}
<div class="row show-grid">
<div class="span3">
IndexCtrl > block141 =
<br>
{{block141}}
</div>
<div class="span3" ng-controller="MyCtrl142">
MyCtrl142 > block142 =
<br>
<button ng-click="aMyCtrl142()">- ! -</button>
<br>
{{block142}}
</div>
</div>
</div>
function MyCtrl14($scope, notify) {
$scope.block141 = '111';
$scope.aMyCtrl14 = function(){
$scope.block141 = '333';
$scope.block142 = '444';
}
}
function MyCtrl142($scope, newnoty) {
$scope.aMyCtrl142 = function(){
$scope.block141 = '555';
$scope.block142 = '666';
}
}
1) Нажимаем на кнопку "aMyCtrl14" - она вставляет оба значения block141 и block142. 2) Нажимаем на кнопку "aMyCtrl142" - она обновляет только значение block142. Понятно так как дочерняя не имеет по умолчанию возможности работать с областью родителей. НО! 3) Нажимаем на кнопку "aMyCtrl14" - она обновляет только значение block141. Почем Родитель теряет власть над областью после того как в нее было что-то записано дочерним контроллером... Подскажите как можно обновлять информацию из одного контроллера в другом? |
Потому что пока значение не определено, оно ищется у родителей вверх по цепочке. Потом оно перезаписывается локальным и больше не зависит от родителей.
|
А принудительно как внести изменения в дочернем элементе?
Может проще отказаться от 2-х Контроллеров и делать все в одном? |
| Часовой пояс GMT +3, время: 14:37. |