2015-10-27 2 views
1

Я пытаюсь создать приложение angularjs, где некоторый контент уже отправлен с первым запросом и, следовательно, показан пользователю до того, как angularjs даже загрузится. В случае, если пользователь очень быстро и уже вводит некоторые данные в текстовое поле (input type = "text"), тогда эти данные теряются после того, как угловые-js связывают.angularjs dynamic init через пользовательский ввод

Как я могу предотвратить это?

Приветствия, Роберт

Редактировать В качестве примера, я мог бы получить следующее с сервера

<html> 
... 
<body ng-app="app"> 
    <div ng-controller="LoginCtrl"> 
    <div ui-view> 
    <!-- start template which was sent with the initial request, corresponds to login.tpl --> 
    <input type="text" id="username" ng-model="credentials.username"/> 
    <input type="password" ng-model="credentials.password"/> 
    <!-- end template --> 
    </div> 
    </div> 
</body> 
</html> 

app.js:

app.config(function($stateProvider){ 
... 
//at this point the input of the user is still in the textbox 
$stateProvider.state('login', { 
    resolve: { 
     credentials : function(){ 
      var username = $('#username'); 
      if (username) { 
       username = username.val(); 
      } 
      //username is always empty, the binding process has already reset the input field 
      return username 
     } 
    }, 
    url: '/login', 
    templateProvider: function($templateFactory) { 
     var username = $('#username'); 
     if (username) { 
      username = username.val(); 
     } 
     //username is always empty, the binding process has already reset the input field 
     return $templateFactory.fromUrl("login.tpl"); 
    }, 
    controller: function(username){ 
     //username is always empty 
    }, 
    data : { 
     requireLogin : false 
    } 
}); 
... 
}); 

app.run(function($rootScope) { 
    //username is still in the textbox 
    $rootScope.$on('$stateChangeStart', function(event, toState, toParams) { 
     //username is not in the textbox anymore 
    }); 
}); 

Я использую угловое разрешение ui-router для маршрутизации. Я попытался перехватить привязку в нескольких местах. Сначала я попытался получить вход пользователя в разрешении (с помощью jquery, потому что я хочу, чтобы вход перед угловым удалением его, поэтому я не могу использовать угловой для этой задачи), но на этом этапе имя пользователя уже пусто. Я также пытался сделать это в templateProvider, но это даже выполняется позже и, следовательно, слишком поздно. Я также пытался прослушать $ stateChangeStart в app.run, но имя пользователя также больше не находится в текстовом поле (все же, оно есть в app.run в начале - привязка должна происходить где-то в то же время) Я довольно уверен, что мне нужно как-то перехватить привязку, но я не знаю, как я могу ее достичь, не ставя директиву по каждому полю ввода, чего я не хочу делать.

+0

Фактически, ваши решения не имеют смысла. Почему вы используете JQuery здесь? – Claies

+0

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

+0

Постараюсь уточнить, пожалуйста ... –

ответ

0

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

Исходный код можно найти здесь: https://github.com/robstoll/angular-pre-work/blob/master/src/pre-work.js

Я в основном поместить шаблон в собственном элементе, который я отмечаю с директивой предварительно данных. Затем директива кэширует содержимое как шаблон - вероятно, похоже на тег < типа = «текст/ng-template» >, но директива pre-work дополнительно собирает все ng-модели, размещенные на входах, и сохраняет их .val(), которые затем могут быть сливается в $scope с дополнительной услугой.

Я думаю, что это достаточно хорошо работает - попробуйте сами, комментарии оценили, так как я довольно новыми для AngularJS: http://plnkr.co/edit/98AdSYCnwzIkqocDwlHq

Единственное, что по-прежнему беспокоит меня, что я теряю фокус, когда угловой загружен. Я могу получить элемент, который имеет текущий фокус в app.run(), но я пока не знаю, когда его устанавливать, где, в каком месте кода, соответственно. Но, я думаю, я тоже это выясню.

Редактировать

Я мог бы также решить проблему потери фокуса. Мне нужно было обернуть утверждение, которое устанавливает фокус внутри $ timeout (delay 1ms). Похоже, угловатые потребности сначала сделать что-то еще. Здесь код, который я использую

app.run(['$rootScope',function($rootScope){ 
    $rootScope.lastFocusedElement = angular.element(document.activeElement).attr('ng-model'); 
    var deregister = $rootScope.$on('$viewContentLoaded', function(){ 
     if ($rootScope.lastFocusedElement) { 
      $timeout(function(){ 
       var elem = document.querySelector('[ng-model="' + $rootScope.lastFocusedElement + '"]'); 
       elem.focus(); 
      }, 1); 
      deregister(); 
     } 
    }); 
}]); 
0

Вы можете попытаться предотвратить показ материала до того, как угловой будет готов к ngCloak.

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