2015-10-27 17 views
1

我试图建立一个angularjs应用内,其中一些内容已经与所述第一请求发送,并因此向用户显示之前angularjs甚至已经加载。如果用户非常快速并且已经将一些数据输入到文本框(输入类型=“文本”),那么一旦angular-js执行绑定,该数据就会丢失。angularjs动态初始化经由用户输入

我如何避免这种情况?

干杯, 罗伯特

编辑作为一个例子,我可以从服务器获取以下

<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 
    }); 
}); 

我使用angular-用于路由的ui路由器。我试图在几个地方拦截绑定。首先,我尝试着解析用户输入(使用jquery,因为我希望在角度清除之前输入,所以我不能在这个任务中使用angular),但是在这个阶段用户名已经是空的。 我也尝试过在templateProvider中做到这一点,但是它甚至会在晚些时候执行,因此太迟了。 我也试图听$ stateChangeStart在app.run但用户名也不再在文本框中(然而,这是没有在年初app.run - 绑定必须在此期间发生的地方) 我很确定我需要以某种方式拦截绑定,但是我不知道如何在不对每个输入字段进行指示的情况下实现它,这不是我想要做的。

+0

事实上,你的决议没有意义。你为什么在这里使用JQuery? – Claies

+0

你说得对,我的错误,解决之前来了templateProvider。但是,在这个阶段,文本框已经被清除了。我正在使用jquery,因为我想在angular绑定模型之前获取用户的输入,以便我可以相应地初始化模型。我也可以使用纯JavaScript,但肯定没有角度。 –

+0

我会尽力澄清,请稍等...... –

回答

0

我没有找到没有使用指令的解决方案。但是,我可以通过指令的帮助和额外的服务来实现我想要的。

的源代码可以在这里找到: https://github.com/robstoll/angular-pre-work/blob/master/src/pre-work.js

我基本上把模板在自己的元素,我用数据预处理指令标记。然后该指令将内容缓存为模板 - 可能类似于< script type =“text/ng-template”>标签,但pre-work指令另外收集所有放置在输入上的ng模型并保存它们的.val(),然后可以是与附加服务合并为$scope

我觉得它工作得很好 - 自己试试它了,赞赏的评论,因为我是相当新的AngularJS:http://plnkr.co/edit/98AdSYCnwzIkqocDwlHq

仍然困扰着我的唯一的事情是,我失去了焦点加载角时。我可以得到当前焦点在app.run()中的元素,但我还不知道何时设置它,分别在哪个代码位置。但我想我也会发现。

编辑

我也可以解决松动的焦点问题。我需要包装在$ timeout(延迟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也许准备好了。