2015-02-11 3 views
3

Я недавно начал изучать и использовать AngularJS, и я до сих пор не понял, о какой концепции.

Мой вопрос: в моем приложении у меня есть контроллер, который использует $http для извлечения данных из моего back-end, как только он будет инициализирован. После отличной обучающей программы CodeSchool на Угловое я пришел с этим:

app.controller("agentController", function ($http) { 
    var agentsCtrl = this; 
    agentsCtrl.agents = []; 
    $http.get("getAgents").success(function (data) { 
     agentsCtrl.agents = data; 
    }); 
... 

HTML:

<div ng-controller="agentController as agentCtrl"> 
    <div ng-repeat="agent in agentCtrl.agents"> 
... 

Это прекрасно работает, но я не ясно, почему я должен был бы объявить контроллер в качестве переменная внутри себя, используя this. Из того, что я понимаю, это потому, что, сделав это, я могу позвонить в службу $http, где ключевое слово this вернет неправильный охват. Это верно?

Я обнаружил, что это также работает:

app.controller("agentController", function ($http, $scope) { 
    $scope.agents = []; 
    $http.get("getAgents").success(function (data) { 
     $scope.agents = data; 
    }); 

HTML:

<div ng-controller="agentController as agentCtrl"> 
    <div ng-repeat="agent in agents"> 
... 

Я предполагаю, что это работает, потому что я явно впрыскивать объем и использовать его в рамках услуги. Кроме того, HTML теперь немного отличается. В первом случае мне нужно явно позвонить agentCtrl.agents, а с помощью области просто позвоните по номеру agents. Это все еще так, потому что переменная теперь объявлена ​​в области, а не в контроллере? Это верно?

Какова наилучшая практика использования в подобных случаях?

Спасибо!

ответ

1

Вопрос 1:

Вы должны сохранить ссылку на объем var agentsCtrl = this, потому что ваши создают анонимную функцию, чтобы быть используется как обратный вызов. Когда вы это сделаете, переменная контекста (this) будет окном.

app.controller("agentController", function ($http) { 
    // this == your controller 
    var agentsCtrl = this; 

    $http.get("getAgents").success(function (data) { 
     // Anonymous function 
     // this == Window Object 
    }); 
}); 

Вопрос 2:

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

$scope.agents = []; // From controller 

И

{{ agents }} // From view (you don't need to specify the $scope variable) 

Я предпочитаю, чтобы дать псевдоним для контроллера и использовать его в моем HTML, как вы это делали в

<div ng-controller="agentController as agentCtrl"> 
    <div ng-repeat="agent in agents"> 
... 

Но оба пути правильно и будет работать нормально ,

+0

То, что мне было интересно. Спасибо за Ваш ответ! – RiccardoNovaglia

2

Вы спрашиваете о 2 разных подходах - «Контроллер как» или «$ scope».

$ Сфера

Оригинальное использование для сферы связывания будет:

<div ng-controller="MainController"> 
    {{ someObj.someProp }} 
</div> 
app.controller('MainController', function ($scope) { 
    $scope.someObj = { 
    someProp: 'Some value.' 
    }; 
}); 

"Контроллер как"

Используя эту технику, вы можете использовать привязку следующим образом :

<div ng-controller="MainController as main"> 
    {{ main.someProp }} 
</div> 
app.controller('MainController', function() { 
    this.someProp = 'Some value.' 
}); 

Оба работают и, оба отлично. Главное отличие - предпочтение.

Тем не менее, большая часть сообщества предпочитает «Контроллер как», почему?

  1. читаемым - Вы всегда можете посмотреть на DOM элемент и понять, что модель осциллографа связан с
  2. Testable - Не имея впрыснуть $ объем делает тестовый код немного легче
  3. больше подходит для зрения углового 2.0, где контроллер намного больше функция конструктора, чем функция, которая добавляет материал в $ объеме
+0

Спасибо за ваш ответ. Я понимаю вашу точку зрения по поводу конвенции. Мой вопрос был больше о том, почему я объявляю переменную и присваиваю ей это в первом случае. Правильны ли мои предположения? Должно ли это преодолеть проблему охвата, с которой я столкнулся при использовании службы '$ http'? – RiccardoNovaglia

1

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

Например:

app.controller('MainCtrl', function() { 
    this.test = 'test'; 

    angular.forEach(testArray, function (item) { 
    console.debug(this.test); 
    }); 
}); 

this.test не определен, как сфера это изменилось.

Plunkr

с помощью переменной фиксирует это:

app.controller('MainCtrl', function() { 
    var vm = this; 

    vm.test = 'test'; 
    var testArray = [ 
    1, 2, 3, 4 
    ]; 

    angular.forEach(testArray, function (item) { 
    console.debug(vm.test); 
    }); 
}); 

Plunkr

Оригинал заявление взято из John Papa's style guide

+0

Это здорово, спасибо! И спасибо за ссылку на руководство по стилю! – RiccardoNovaglia

+1

Не беспокойтесь. Вы можете поблагодарить меня еще по голосу за мой ответ :) –

+0

Извините, у меня не хватило репутации! Просто сделал :) :) – RiccardoNovaglia

1

Это для ответа на ваш комментарий к ответу Бен Diamant в.

less traditional alias syntax (as Alias) упрощает ваш код и, вероятно, дает более четкое представление о том, что вы пытаетесь сделать с тем, кто читает ваш код.

От ng-controller spec:

Использование controller as

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

  • Если вы пишете свои контроллеры в качестве классов, у вас есть более легкий доступ к свойствам и методам, которые появятся в области, изнутри кода контроллера.

  • Поскольку всегда есть.в привязках вам не нужно беспокоиться о прототипальных примитивах маскирования наследования.

Check out also this awesome explanation of the advantages of alias syntax.

Среди преимуществ одним наиболее важным является то, что синтаксис псевдоним позволяет

относятся к контроллеру мы хотим обратиться и перестать беспокоиться о тонкости наследования Scope.

Надеюсь, это поможет.

+0

Очень полезно! Благодаря! – RiccardoNovaglia

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