AngularJS и параметры контроллеров

Те люди, которые работают с AngularJS, знают про директиву ngController. В нее передается функция, описывающая поведение блока с директивой. И тут начинается магия! Если наша функция выглядит так:

SomeController = function ($scope) {...};

то она будет вызвана с одним параметром — scope, связанным с контроллером. А если, она выглядит, например, так:

SomeController = function ($http, $location, $scope) {...};

то передаваемых параметров станет внезапно три: два системных сервиса ($http и $location) и тот же самый scope.

Так как же фреймворк определяет, какие параметры нужны для вызова контроллера? Эта магия называется Function.toString(). Метод toString() у функции возвращает ее текст, а дальше дело техники: /^function\s*[^\(]*\(\s*([^\)]*)\)/m. Получили имена параметров, разобрали, подставили. Вот такой нетривиальный подход.

Детали можно посмотреть в исходниках.

AngularJS

Вы, наверное, слышали об этом JavaScript-фреймворке. Модный тренд, если позволите так выразиться. Superheroic JavaScript MVW1 Framework, как утвержают сами разработчики. Не удержался и посмотрел на него, тем более что выдалась возможность сделать это в рабочее время и за счет заказчика. Мы выбираем основу для будущего проекта, вот и решили глянуть современные js фреймворки, и мне достался AngularJS. Поделюсь своими впечатлениями.

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

<table class="table table-striped table-hover" ng-controller="TestController">
    <thead>
        <tr>
            <th>Action</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="action in actions">
            <td>{{action.action}}</td>
        </tr>
    </tbody>
</table>

Дальше мы подключаем JavaScript:

function TestController($scope) {
    $scope.actions = [
        {action: 'Action1'},
        {action: 'Action2'}
    ];
}

Ну и всё. У нас готова страница с таблицей, в которой 2 строки: «Action1» и «Action2». Но это еще не все. Если мы потом добавим в поле actions еще чего-нибудь, то оно тоже автоматически отобразится на странице.

Единственное, мне потребовалось некоторое время, чтобы разобраться с некоторыми более сложными вещами. Например, создание независимых компонентов. В моей задаче требовалось, чтобы родительский компонент передавал данные для дочернего. В результате оказалось, что на момент вызова родительского контроллера дочерний еще не инициализирован и нужно немного подождать. И лучше всего использовать для этого событие $viewContentLoaded. Чтобы это понять, официального сайта было недостаточно, и пришлось провести пару-тройку часов в обнимку с дебаггером и гуглом.

В общем, впечатление от фреймворка очень положительное, надо будет попробовать написать что-нибудь более-менее серьезное.

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


  1. Model-View-Whatever