Те люди, которые работают с AngularJS, знают про директиву ngController. В нее передается функция, описывающая поведение блока с директивой. И тут начинается магия! Если наша функция выглядит так:
SomeController = function ($scope) {...};
то она будет вызвана с одним параметром — scope, связанным с контроллером. А если, она выглядит, например, так:
SomeController = function ($http, $location, $scope) {...};
то передаваемых параметров станет внезапно три: два системных сервиса ($http и $location) и тот же самый scope.
Так как же фреймворк определяет, какие параметры нужны для вызова контроллера? Эта магия называется Function.toString()
. Метод toString()
у функции возвращает ее текст, а дальше дело техники: /^function\s*[^\(]*\(\s*([^\)]*)\)/m
. Получили имена параметров, разобрали, подставили. Вот такой нетривиальный подход.
Детали можно посмотреть в исходниках.
Вы, наверное, слышали об этом 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
. Чтобы это понять, официального сайта было недостаточно, и пришлось провести пару-тройку часов в обнимку с дебаггером и гуглом.
В общем, впечатление от фреймворка очень положительное, надо будет попробовать написать что-нибудь более-менее серьезное.
Еще примеры можете оценить на главной странице фреймворка, они там гораздо лучше, чем я вам привел.
Model-View-Whatever