2016-09-03 5 views
0

は、私は次のシナリオのための良い方法を定義するために苦労しています:ネスティングコントローラとディレクティブ

私はLaravel建てAPIを消費AngularJsアプリを持っています。

マイタスクのインデックスページには、タスクが一覧表示されます。リストの一番下には、タスクの2つの基本要件を入力できる新しいエントリ行があり、新しいタスクが(私のAPIを呼び出すサービスを介して)作成され、項目が範囲内にプッシュされます。

ここで問題が発生します。ユーザーが既存のタスクをクリックすると、タスクのすべての詳細が表示されるサイドバーが開きます。すべての詳細は編集可能で、サブタスク、添付ファイルなどの追加も含まれます。APIアップデートメソッドを呼び出すにはsaveをクリックする必要がありますが、タスクがリスト内で更新されているためサイドバーで変更が行われているため、どういうわけか、タスクリストのスコープをタスクサイドバーから切り離したいのですが、タスクが保存されるときにリストを明示的に更新してください。

My TasksControllerは非常に奇抜であります。現時点では、「selectedTask」変数を(選択したタスクを使用して)作成し、サイドバー・ビューで使用するng-click機能があります。

私は良い方法があることを知っています。ディレクティブを使ってタスクサイドバー用の新しいコントローラを作成しようとしましたが、データのやりとりをどのように行うことができないか分かりません。

私はから来ていますかを理解するのに役立ついくつかのコード:

app.jsルート

.state('root.tasks', { 
    url: '/tasks', 
    views: { 
     '[email protected]': { 
      templateUrl: '../partials/tasks-index.html', 
      controller: 'TasksController as TasksCtrl' 
     }, 
     '[email protected]': { 
      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."); 
    }); 
}; 

答えて

1

あなたはJSON.parse(JSON.stringify(タスク))を使用して、サイドバーにタスクオブジェクトのクローンを作成し、サイドバーの範囲にクローン化されたオブジェクトを置くことができます。これはサイドバーコントローラで1回発生し、すべての入力はクローンオブジェクトを更新する必要があります。

ユーザーが[保存]をクリックすると、変更された実際のタスクキーにコピーされます。たとえば、これを拡張することができます。実際のセーブはサイドバーコントローラで行うことができます。または、rootScopeでイベントを発行し、タスクコントローラでイベントをリッスンすることもできます。

+0

Iイベントリスナーについて考えましたが、膨大な数のタスクが発生しています。これは、パフォーマンスに関する問題がイベントを絶えず監視する原因にはなりませんか?私はタスクをクローンすることができますが、どうすれば元に戻すことができますか? – DJC

+0

タスク・アップデート・イベントは、タスク・コントローラで1回、またはタスク・サービスで一度監視されます。それはあなたが持っている仕事の数とは何の関係もありません。更新されたタスクIDと詳細をイベントの引数として送信できます。バインディングが引き続き機能するように、元のタスクに属性をコピーし直す(タスクを置き換えない)ことを覚えておいてください。この種のコピーは、拡張で行うことができます。 – Nitzo

+0

ありがとう私はこれも行くよ – DJC

1

@Nitzoの回答を完了するつもりですが、イベントを使用する代わりに、タスク用のサービスを作成する必要があります。

ユーザーがタスクをクリックすると、そのタスクをクローンする必要があります(ユーザーangular.copy()またはJSONのアプローチが可能)。複製されたタスクと元のタスクをサービスに保存します。

ユーザーがタスクを保存すると、(ユーザーが変更/更新した)クローンタスクを取得し、元のオブジェクト(ユーザーangular.extend())とマージします。

サービスなので、問題なくすべてのコントローラ間で共有できます。スニペットをガイドラインとして使用することができます=)。 (私はまだあなたは、私がチェックアウトこの素晴らしいangular-styleguide使用パターンをundestandすることは困難見つけた場合、私の角度スキルに改善するためにたくさん持って、私が使用し何かを逃した場合、私を修正してください)

angular.module('main', []) 
 
    .factory('taskService', taskService) 
 
    .controller('TaskListController', TaskListController) 
 
    .controller('TaskFormController', TaskFormController); 
 

 
function taskService() { 
 
\t var service = { 
 
\t \t selectedTask: null, 
 
\t \t editingTask: null, 
 
\t \t tasks: [], 
 
\t \t load: load 
 
\t }; 
 

 
\t function load() { 
 
\t \t service.tasks = [{name: "t1", value: 1}, {name: "t2", value: 1}] 
 
\t } 
 

 
\t return service; 
 
} 
 

 
TaskListController.$inject = ['taskService']; 
 
function TaskListController(taskService) { 
 
\t var vm = this; 
 

 
\t vm.taskService = taskService; 
 
\t vm.editTask = editTask; 
 
    taskService.load(); 
 

 
\t function editTask(task) { 
 
\t \t taskService.selectedTask = task; 
 
\t \t taskService.editingTask = angular.copy(task); 
 
\t } 
 

 
} 
 

 
TaskFormController.$inject = ['taskService']; 
 
function TaskFormController(taskService) { 
 
\t var vm = this; 
 

 
\t vm.taskService = taskService; 
 
\t vm.saveTask = saveTask; 
 

 
\t function saveTask() { 
 
     if (taskService.selectedTask) { 
 
\t \t angular.extend(taskService.selectedTask, taskService.editingTask); 
 
\t \t taskService.selectedTask = null; 
 
     } else { 
 
     taskService.tasks.push(taskService.editingTask); 
 
     } 
 
     
 
     taskService.editingTask = null; 
 
\t } 
 

 
}
.task_item { 
 
    cursor: pointer; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<div ng-app="main"> 
 

 
\t <ul ng-controller="TaskListController as listCtrl"> 
 
\t \t <li ng-repeat="task in listCtrl.taskService.tasks" 
 
\t \t \t ng-click="listCtrl.editTask(task)" class="task_item"> 
 
\t \t \t {{task.name}} - {{task.value}} 
 
\t \t </li> 
 
\t </ul> 
 
\t 
 
\t <form ng-controller="TaskFormController as formCtrl" ng-submit="formCtrl.saveTask()"> 
 
\t \t <input type="text" placeholder="name" ng-model="formCtrl.taskService.editingTask.name"></input> 
 
\t \t <input type="number" placeholder="value" ng-model="formCtrl.taskService.editingTask.value"></input> 
 
\t \t <input type="submit"></input> 
 
\t </form> 
 

 
</div>

+0

ありがとうこれは良い解決策のように思える。完全性とこれに遭遇する可能性のある人たちのために、いくつかのコードを提供することができますか?私は喜んで正しいとマークしたい。 – DJC

+0

なぜですか?ちょうどスニペット=)を投稿し、それがあなたが探していた/期待していることを教えてください –

関連する問題