仅在点击某处时,angularjs才会在模型中进行更改

时间:2017-09-20 18:18:12

标签: javascript angularjs firebase firebase-realtime-database

我正在使用firebase和angular js开发搜索建议功能。基本上在搜索输入框的键盘上,我调用以下函数:

scope.suggestString = {};

    scope.search = function(){
        scope.suggestString = {};

        firebaseDb.ref("users")
        .orderByChild("Name")
        .startAt(scope.searchedString)
        .endAt(scope.searchedString + "\uf8ff")
        .on("value", function(snapshot) {
            snapshot.forEach(function(childSnapshot) {
                if(scope.suggestString.hasOwnProperty(childSnapshot.key) == false){
                    scope.suggestString[childSnapshot.key] = childSnapshot;
                }
            });
        });
    }

HTML:

<form>
    <input type="text" ng-model="searchedString" ng-keyup="search()">                   

    <ul>
       <li ng-repeat="(key,item) in suggestString">
         <a href="#/home/{{key}}">{{item.val().firstName}}</a>
      </li> 
    </ul>

</form>

代码工作,调用到firebase并获取记录但我必须在搜索输入框中的某处单击以显示建议。 我尝试使用范围。$ apply()但它不起作用。它说已经应用了范围

3 个答案:

答案 0 :(得分:2)

也许你可以使用类似的东西:

<input ng-model="searchedString" ng-model-options="{debounce: 1000}" type="text"> 

在输入框上,输入元素中的搜索字符串将在输入元素中更新ng-model(searchString),输入时间延迟1秒。

之后你可以输入类似的内容:

scope.$watch('searchedString', (newVal,oldVal)=>{
     scope.suggestString = {};

        if(scope.searchedString.length <3){
            return;
        }

        firebaseDb.ref("users")
        .orderByChild("Name")
        .startAt(scope.searchedString)
        .endAt(scope.searchedString + "\uf8ff")
        .on("value", function(snapshot) {
            snapshot.forEach(function(childSnapshot) {
                if(scope.suggestString.hasOwnProperty(childSnapshot.key) == false){
                    scope.suggestString[childSnapshot.key] = childSnapshot;
                }
            });
        });
});

现在,如果您获取数据的代码是正确的,它应该可以正常工作。

答案 1 :(得分:0)

Angular不知道这个异步调用,所以你必须触发一个摘要。在得到响应后,您可以通过调用constructor(iconRegistry: MdIconRegistry, sanitizer: DomSanitizer) { this.iconList.forEach((iconName) => { iconRegistry.addSvgIcon( iconName, sanitizer.bypassSecurityTrustResourceUrl('assets/img/examples/' + iconName + '.svg')); }); } 来安全地执行此操作而不会出现控制台错误:

$evalAsync

但我怀疑// ... .on("value", function (snapshot) { scope.$evalAsync(function () { snapshot.forEach(function (childSnapshot) { if (scope.suggestString.hasOwnProperty(childSnapshot.key) == false) { scope.suggestString[childSnapshot.key] = childSnapshot; } }) }); }); 也会没问题,如果你在循环之外做的就像我上面那样。

另一种选择是将所有这个firebase功能包装到一个单独的函数中(可能在服务中),并使用scope.$apply服务从该函数返回一个promise,并解析firebase响应。然后您不必手动触发摘要,因为Angular知道$q服务。

答案 2 :(得分:-1)

Safe apply是我正在寻找的东西,现在搜索很顺利。