В основном сайт PJAX с некоторыми AngularJS

У меня есть сайт, использующий PJAX повсюду, и у меня есть несколько страниц, использующих AngularJS. Для страниц AngularJS я хотел бы продолжить использовать PJAX, чтобы получить все преимущества, связанные с отказом от перезагрузки всей HTML-страницы, ресурсов и т. Д. К сожалению, PJAX просто загружает HTML-код на страницу и не запускает какой-либо javascript. Это нормально, потому что я могу запустить javascript вручную при успешном выполнении pjax, но я не могу понять, что заставляет AngularJS инициализироваться.

Для простого сценария допустим, что я использую AJAX следующий HTML-код на странице. Также предположим, что на странице уже был включен Angular.js. Что я могу назвать, чтобы следующее работало как приложение Angular?

<div>
  <label>Name:</label>
  <input type="text" ng-model="yourName" placeholder="Enter a name here">
  <hr>
  <h1>Hello {{yourName}}!</h1>
</div>

Спасибо


person jrhicks    schedule 14.10.2012    source источник
comment
$compile можно использовать сервис.   -  person Tosh    schedule 15.10.2012
comment
Ручная инициализация оказывается весьма полезной, docs.angularjs.org/guide/bootstrap ... его работаю за исключением того, что что-то преобразует мои усы}} в hrefs в% 20% 7D% 7D ... Сейчас я пытаюсь понять, что это делает или что с этим можно сделать. AngularJS работает там, где}} не кодируются.   -  person jrhicks    schedule 15.10.2012


Ответы (3)


angular.bootstrap(...) не бросил работу для меня, это бросало

Ошибка уже существующего приложения.

Поэтому я выбрал решение (re)$compile, но когда дело доходит до использования angular вне фреймворка (например, как вызвать $ compile), документов мало. После многих проб и ошибок это сработало для меня, хотя могут быть некоторые накладные расходы:

  // outside of angular...
  var ngRefresh = function() {
    var scope = angular.element("body").scope();
    var compile = angular.element("body").injector().get('$compile');

    compile($("body").contents())(scope);
    scope.$apply();
  }

  // PJAX
  $('#page').on('pjax:success', function(e){
    ngRefresh();
  });
person charlysisto    schedule 18.09.2013
comment
Разве это не оставляет оставшиеся элементы в области видимости? Когда я пробую это локально, мои возможности становятся все больше и больше. - person Sebastian Hoitz; 23.03.2016

Ручная инициализация работала нормально

  angular.element(document).ready(function() {
     angular.bootstrap(document);
   });

У меня возникли некоторые проблемы с gem rack-pjax, потому что он избегал усов в моих URL-адресах, поэтому я просто избавился от промежуточного программного обеспечения и решил, что веб-сервер обнаружит pjax в запросе и откажется от рендеринг макета.

person jrhicks    schedule 14.10.2012

Начиная с решения, предоставленного @charlysisto, я добавил ловушку в pjax:beforeReplace, чтобы очистить старую область видимости:

var cleanupRemovedScopes = function() {
  var $scope = angular.element("body").scope();

    var q = [$scope], scope, first = true;
    while (q.length > 0) {
        scope = q.pop();

        if (!first) {
            scope.$destroy();
        }

        first = false;

        if (scope.$$childHead) {
            q.push(scope.$$childHead);
        }

        if (scope.$$nextSibling) {
            q.push(scope.$$nextSibling);
        }
    }
}

$('#page').on('pjax:beforeReplace', function() {
  var $timeout = angular.element("body").injector().get("$timeout");
  $timeout(function() {
    cleanupRemovedScopes();
  }
}

Однако ограничение этого сценария очистки заключается в том, что ваш вызов PJAX заменяет все тело.

person Sebastian Hoitz    schedule 23.03.2016