2016-09-04 1 views
1

Я пытаюсь понять, как правильно работать с данными в Угловом 1.Правильно работать с данными в угловом

Я использую компонентный подход. Рассмотрим простой случай. У меня есть боковая навигация и приборная панель. Мне нужно показать данные отделов в этих компонентах.

import sidenavHtml from './sidenavigation.html'; 
import sideNavController from './sidenavigation.controller'; 

export default SideNavigation; 

SideNavigation.$inject = [ 
]; 

function Sidenav() { 
    return { 
     restrict: 'E', 
     scope: {}, 
     template: sidenavHtml, 
     controller: sideNavController, 
     controllerAs: 'ctrl', 
     link: function ($scope, elem, attrs) { 

     } 
    }; 
} 

export default class SideNavigationController { 
    ... 

    $onInit() { 
     this.getDepartments(); 
    } 

    getDepartments() { 
     this.departmentService.getDepartments().then((result) => { 
      this.departments= result.data; 
     }); 
    } 
} 

export default class DashboardController { 
    ... 

    $onInit() { 
     this.getDepartments(); 
    } 

    getDepartments() { 

     this.departmentService.getDepartments().then((result) => { 
      this.departments= result.data;    
     }); 
    } 
} 

export default Departments; 

function Departments($http) { 

    function getDepartments() { 
     return $http({url: 'http://localhost:9000/api/departments', method: 'GET'}); 
    } 

    function create(newDepartment) { 
     return $http.post('http://localhost:9000/api/departments', newDepartment); 
    } 

    return {getDepartments, create}; 
} 

В компоненте пользователя Dashboard может создать новый отдел (создание еще один компонент, который вызывается из Dashboard компонента). Когда пользователь создал новый отдел, я должен уведомить об этом SideNavigation и Dashboard. Так, в Dashboard и SideNavigation компонентов я использую следующий код: this.$rootScope.$on('updateDepartmens',()=> { this.getDepartments(); });

Ну, недостатки этого ПОДХОД очевидны. Когда мое приложение отображается, я получаю два HTTP-запроса, и я использую $rootScope. Я решил переписать сервис следующим образом:

export default Departments; 

    function Departments($http) { 
     this.departments; 

     function getDepartments() { 
      if(!departments) { 
      $http({url: 'http://localhost:9000/api/departments', method: 'GET'}) 
      .then((response) => {     
       this.departments = response.data;      
      }) 
      .catch((err) => { 
       console.log('error'); 
      }); 
      } 

      return this.departments; 
     } 

     function create(newDepartment) { 
      $http.post('http://localhost:9000/api/departments', newDepartment) 
      .then((response) => { 
       // handle response and add to departments; 
       ... 
       this.departments.push(response.data); 
      ); 
    } 

     return {getDepartments, create}; 
    } 

Как вы думаете, это хороший подход, или есть другой способ?

Как вы думаете, должен ли я использовать этот подход в целом или использовать свой первый подход (метод вызова службы, который делает HTTP-запрос), когда мне не нужны данные совместного доступа и использование второго подхода (привязка к переменной), когда мне нужно обмениваться данными ?

Еще один вопрос. Используете ли вы модели сопоставления серверов для моделей клиентов или используете только объекты, возвращаемые с сервера?

ответ

1

Как вы думаете, это хороший подход или есть другой способ?

Я думаю, что ваш второй подход правильный, но если вы хотите перехватить определенное событие, например, перезагрузить данные, когда оно будет извлечено, вы не хотите автоматически выполнять определенную функцию, связанную с этим событием каждый время.

У меня была аналогичная проблема в последнее время, мне нужно было выполнить функцию только тогда, когда данные были извлечены factory. Я ненавижу использовать $rootScope для таких вещей. Мне не нравится использовать его, потому что это делает приложение грязным, и я также заметил побочные эффекты на тестах приложений. Но, как вы знаете, использование $rootScope таких событий, как $broadcast и $on, действительно хорошо.

Я нашел лучший способ реализовать такую ​​вещь. Используя Postal.js, вы можете создавать виртуальные шины в своем приложении, которые разделяются между компонентами, которые вы хотите. Например, вы можете подписаться на канал reloadItems как с DataFactory, так и с DataController, и вы будете излучать только на этом канале, чтобы вы извлекли элементы и перехватили это сообщение на своем контроллере и выполнили функцию, связанную с этим событием. После этого, если хотите, вы можете отказаться от подписки с этого канала и освободить эту шину. Вы можете разделить конкретную шину с n различными модулями.

Я заметил, что использование этой библиотеки увеличивает общую скорость моего приложения, так как я не прикрепляю ничего к $rootScope.

Вот пример использования

// . . . Cool stuff 
//Factory 
$scope.$bus.publish({ 
        channel : 'reloadItems', 
        topic : 'reloadItems' 
        data : items 
); 

// . . . Cool Stuff also 
//Controller 
$scope.$bus.subscribe({ 
    channel : 'reloadItems', 
    topic : 'reloadItems', 
    callback : function() { 
    reloadItems(); 
    } 
}); 

Я действительно предлагаю вам дать ему шанс. Вы можете найти интересную статью о том, как использовать ее с Angular here.

Как вы думаете, должен ли я использовать этот подход в целом или использовать свой первый подход (метод вызова, который делает HTTP-запрос), когда мне не нужны данные совместного доступа и использование второго подхода (привязка к переменной), когда мне нужно обменяться данные?

Я чувствую, что вы не должны связывать эти вещи с переменной. Просто используйте события для управления этим. И, как я уже говорил, ваш второй подход лучше и более модульный.

Вы используете модели серверов сопоставлений для моделей клиентов или просто используете объекты, возвращаемые с сервера?

Лично я просто использую объекты, возвращенные с сервера. Мне нравится иметь тонкий интерфейс и я использую синтаксический анализ данных в фоновом режиме, но если мне как-то нужно работать с данными в интерфейсе, я никогда не делаю этого в контроллерах, я делаю это в Фабрики или Услуги.

Я надеюсь, что был полезным.

+1

Большое спасибо за ответ. Я обязательно посмотрю на эту библиотеку. – user348173

Смежные вопросы