这让我感到烦恼。 我有一个处理徽标面板的服务和一个用于在不同面板之间导航的功能。
当调用 getPanels 时,如果所有承诺都有,则会在服务上设置 currentPanel ,索引和长度已完成(请参阅 getPanels 方法中的 $ q.all ):
.service('ConfiguratorLogoService', ['$q', 'UploadService', 'LogoService', 'ArrayService', 'SvgService', function ($q, uploadService, logoService, arrayService, helper) {
// Private function to build a file array
var _buildFileArray = function (panels, files) {
//--- Omitted for brevity ---//
};
// Create our service
var service = {
// Create our arrays
panels: [],
files: [],
currentPanel: null,
index: 0,
length: 0,
// Get our panels
getPanels: function (container, garmentId) {
// Create a deferred promise
var deferred = $q.defer();
// Create our arrays
var panels = []
files = [],
promises = [];
// If we have a container
if (container) {
// Get the containers children
var children = container.children()
// Loop through our panel's children
for (var i = 0; i < children.length; i++) {
// Get the current child
var child = angular.element(children[i]),
childId = child.attr('id'),
childTitle = helper.extractText(childId, ':', 1);
// Create our item
var panel = {
id: childId,
title: childTitle
};
// Try to get our item
promises.push(logoService.get(garmentId, panel.id).then(function (response) {
// If we have any data
if (response) {
// Add the file to our array
files.push(response);
}
}));
// Add our child to the array
panels.push(panel);
}
}
// After all the promises have been handled
$q.all(promises).then(function () {
// Get our files
service.files = _buildFileArray(panels, files);
service.panels = panels;
service.currentPanel = panels[0];
service.length = panels.length;
// Resolve our promise
deferred.resolve({
files: service.files,
panels: panels
});
});
// Return our promise
return deferred.promise;
},
// Get our next panel
navigateNext: function () {
// Create a deferred promise
var deferred = $q.defer();
// Get the next index or reset if we reached the end of our list
service.index = service.index === (service.length - 1) ? 0 : service.index += 1;
// Set our active panel
service.currentPanel = service.panels[service.index];
console.log(service.index);
// Resolve our promise
deferred.resolve();
// Return our promise
return deferred.promise;
},
// Get our previous panel
navigatePrevious: function () {
// Get the previous index or set to the end of our list
service.index = service.index === 0 ? service.length - 1 : service.index -= 1;
// Set our active panel
service.currentPanel = service.panels[service.index];
},
// Removes the file from azure
remove: function (index) {
//--- Omitted for brevity ---//
}
};
// Return our service
return service;
}])
这很好,它工作,并选择第一个面板。 所以,我有一个控制器,它附加到一个指令。控制器如下所示:
.controller('ConfiguratorLogosDirectiveController', ['ConfiguratorLogoService', 'RowService', function (service, rowService) {
var self = this;
// Set our current panel
self.currentPanel = service.currentPanel;
self.index = service.index;
self.length = service.length;
// Initialization
self.init = function (container, garmentId) {
// Get our panels
return service.getPanels(container, garmentId).then(function (response) {
self.panels = response.panels;
self.files = response.files;
// If we have any panels
if (self.panels.length) {
// Set our current panel
self.currentPanel = service.currentPanel;
self.index = service.index;
self.length = service.length;
}
// Return our response
return response;
})
};
// Map our service functions
self.upload = service.upload;
self.next = service.navigateNext;
self.previous = service.navigatePrevious;
self.remove = service.remove;
}])
正如你所看到的,当我拿到我的面板时,我在控制器本身上设置 currentPanel ,索引和长度,我没有#39;我想我必须这样做,因为在调用控制器时,它已经有了对服务值的引用。我认为2路绑定会发挥作用,当服务值更新时,控制器也会更新。
无论如何,我在 getPanels 方法成功完成后更新了值。在我的指示中我有这个:
// Invoke on controller load
controller.init(container, scope.garmentId).then(function (response) {
// Map our properties
scope.panels = controller.panels;
scope.files = controller.files;
scope.currentPanel = controller.currentPanel;
scope.index = controller.index;
scope.length = controller.length;
});
再次正常工作。在我的模板中,我可以看到第一个面板,它看起来很好。 那么,下一步就是我的导航功能。我从 next 开始,我已经为测试目的进行了修改,因此我可以在服务导航功能中输出 controller.index 以及console.log。 指令函数如下所示:
scope.next = function () {
controller.next().then(function () {
console.log(controller.index);
});
};
当调用此方法时,我可以在我的控制台中看到该服务将索引增加1但控制器仍然显示0,这意味着双向绑定不起作用。 我即将在控制器中更新我的方法,将 currentPanel 和索引推送到控制器,但在此之前,我想我会先问这里。
那么,有没有人知道为什么我的2路绑定不起作用?
所以我目前的解决方法有效,但我不喜欢它。 在我的指示中,我做到了这一点:
scope.next = function () {
controller.next().then(function () {
console.log(controller.index);
scope.currentPanel = controller.currentPanel;
scope.index = controller.index;
scope.length = controller.length;
});
}
在指令控制器中我做到了:
self.next = function () {
// Try to navigate forward
return service.navigateNext().then(function () {
// Set our current panel
self.currentPanel = service.currentPanel;
self.index = service.index;
self.length = service.length;
console.log(self.index);
});
}
在我的服务中,它看起来和以前一样:
// Get our next panel
navigateNext: function () {
// Create a deferred promise
var deferred = $q.defer();
// Get the next index or reset if we reached the end of our list
service.index = service.index === (service.length - 1) ? 0 : service.index += 1;
// Set our active panel
service.currentPanel = service.panels[service.index];
console.log(service.index);
// Resolve our promise
deferred.resolve();
// Return our promise
return deferred.promise;
},
这样可行,但肯定不是它的工作方式。