我正在努力为以下场景定义一个好的方法:
我有一个使用Laravel内置api的AngularJs应用程序。
我的任务索引页面列出了任务。在列表的底部是一个新的输入行,可以输入任务的两个基本要求,并创建一个新任务(通过调用我的API的服务),并将项目推入范围。
复杂性来自此处 - 当用户点击现有任务时,会打开侧边栏,其中会显示任务的所有详细信息。所有细节都是可编辑的,包括添加子任务,附件等。他们需要点击保存来调用API更新方法,但由于任务在列表中更新,因为他们在侧边栏中进行了更改,人们正在考虑它已经储蓄了。我想以某种方式将任务列表的范围与任务侧栏分开 - 但显然在保存任务时更新列表。
我的TasksController看起来很不整洁。目前,我有一个ng-click功能,可以创建一个“选择任务”'变量(使用所选任务),然后由侧边栏视图使用。
我知道会有更好的方法。我尝试使用指令为任务侧栏创建一个新的控制器 - 但我很难看到如何来回传递数据。
一些代码可以帮助我们了解我的来源:
app.js路线
.state('root.tasks', {
url: '/tasks',
views: {
'content@root': {
templateUrl: '../partials/tasks-index.html',
controller: 'TasksController as TasksCtrl'
},
'task-detail-sidebar@root.tasks': {
templateUrl: '../partials/task-detail-sidebar.html'
}
}
})
TasksController显示任务功能
vm.showTask = function(task, added) {
// if same task is clicked in list again, or close button clicked, close task
if (vm.selectedTask.id == task.id && vm.clickedShut == false && !added) {
vm.clickedShut = true;
} else {
// else open task sidebar and create selectedTask
vm.clickedShut = false;
task.newSubtask = {'title':'', 'assignees':[task.task_owner]};
vm.selectedTask = task;
// need to grab current owner/assignees so we know if they change when saving - if so, notifications are sent
vm.currentOwner = task.task_owner.id;
vm.currentAssignees = [];
if (task.assignees) {
for (var i = 0; i < task.assignees.length; i++) {
vm.currentAssignees.push(task.assignees[i].id);
}
}
}
};
TasksController updateTask
vm.updateTaskFromSidebar = function() {
TasksService.update(vm.selectedTask).then(function(data) {
if (data.data.task_owner.id !== vm.currentOwner && data.data.task_owner.id !== $rootScope.currentUser.id) {
NotificationsService.updateOwner(data.data, $rootScope.currentUser)
}
var newAssignees = data.data.assignees;
var alertAssignees = [];
if (newAssignees) {
for (var i = 0; i < newAssignees.length; i++) {
if (vm.currentAssignees.indexOf(newAssignees[i].id) === -1 && newAssignees[i].id !== data.data.task_owner.id && newAssignees[i].id !== $rootScope.currentUser.id) {
alertAssignees.push(newAssignees[i]);
}
}
if (alertAssignees.length) {
NotificationsService.updateAssignees(data.data, alertAssignees, $rootScope.currentUser);
}
}
vm.showSimpleToast('Task Saved');
}).catch(function() {
vm.showAlertDialog('Error Updating Task', "We've spotted this and will work to resolve the problem as soon as possible.");
});
};
答案 0 :(得分:1)
您可以使用JSON.parse(JSON.stringify(task))在侧栏中克隆任务对象,并将克隆的对象放在侧栏的范围内。这在边栏控制器中发生一次,所有输入都应更新克隆对象。
当用户单击“保存”时,您将复制回已更改的实际任务键。例如,您可以使用extend。实际的保存可以在侧边栏控制器中完成,也可以在rootScope上发出事件并在任务控制器中监听事件。
答案 1 :(得分:1)
我将完成@Nitzo的答案,而不是使用事件,你应该为你的任务创建一个服务。
当用户单击某个任务时,您应该克隆它(您可以使用angular.copy()或JSON方法)并将克隆的任务和原始任务保存在服务中。
当用户保存任务时,您将获得克隆任务(用户已更改/更新)并将其与原始对象合并(您可以使用angular.extend())。
由于它是一项服务,您可以在所有控制器之间共享它,没有任何问题。您可以使用代码段作为指南=)。 (我仍然有很多提高我的角度技能,如果你发现很难找到我使用的模式结账这个真棒angular-styleguide,如果我错过使用的东西,请纠正我)
angular.module('main', [])
.factory('taskService', taskService)
.controller('TaskListController', TaskListController)
.controller('TaskFormController', TaskFormController);
function taskService() {
var service = {
selectedTask: null,
editingTask: null,
tasks: [],
load: load
};
function load() {
service.tasks = [{name: "t1", value: 1}, {name: "t2", value: 1}]
}
return service;
}
TaskListController.$inject = ['taskService'];
function TaskListController(taskService) {
var vm = this;
vm.taskService = taskService;
vm.editTask = editTask;
taskService.load();
function editTask(task) {
taskService.selectedTask = task;
taskService.editingTask = angular.copy(task);
}
}
TaskFormController.$inject = ['taskService'];
function TaskFormController(taskService) {
var vm = this;
vm.taskService = taskService;
vm.saveTask = saveTask;
function saveTask() {
if (taskService.selectedTask) {
angular.extend(taskService.selectedTask, taskService.editingTask);
taskService.selectedTask = null;
} else {
taskService.tasks.push(taskService.editingTask);
}
taskService.editingTask = null;
}
}
.task_item {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="main">
<ul ng-controller="TaskListController as listCtrl">
<li ng-repeat="task in listCtrl.taskService.tasks"
ng-click="listCtrl.editTask(task)" class="task_item">
{{task.name}} - {{task.value}}
</li>
</ul>
<form ng-controller="TaskFormController as formCtrl" ng-submit="formCtrl.saveTask()">
<input type="text" placeholder="name" ng-model="formCtrl.taskService.editingTask.name"></input>
<input type="number" placeholder="value" ng-model="formCtrl.taskService.editingTask.value"></input>
<input type="submit"></input>
</form>
</div>