1

我遇到了一个问题,我的 Angular 知识太有限而无法弄清楚。我想要一个非 html5 占位符属性。这是我之前在堆栈溢出中发现的一些代码,它可以很好地做到这一点:

// Placeholder for non HTML5 browsers
app.directive("ngPlaceholder", function($log, $timeout) {
    var txt;
    return {
        restrict: "A",
        scope: { txt: "@ngPlaceholder" },
        link: function(scope, elem, attrs) {

            elem.on("focus", function() {
                if(elem.val() === scope.txt) {
                    elem.val("");
                }
                scope.$apply()
            })

            elem.on("blur", function() {
                if(elem.val() === "") {
                    elem.val(scope.txt);
                }
                scope.$apply()
            })

            // Initialise placeholder
            $timeout(function() {
                elem.val(scope.txt)
                scope.$apply();
            })
        }
    }
})

但是......将它与 ng-model 结合使用:

input(
  type="text"
  ng-model="card.number"
  ng-placeholder="0000-0000-0000-0000")

它消除了双向数据绑定!

继承人: http ://plnkr.co/edit/1AvVOxb5O6P5pU3wIuKv?p=preview

我错过了什么?

更新很多人已经在这里表达了解决这个相当烦人的问题的方法

4

4 回答 4

2

使用 $parent 来引用父范围中的模型,因为指令 ngPlaceholder 创建了一个隔离范围。(但这并不是 IE 9 特有的。)

<input type="text" ng-placeholder="0000-0000-0000-0000" ng-model="$parent.card.number2"/>
于 2013-08-22T17:07:48.440 回答
2

这个解决了$timeout延迟,$scope可能同时改变的问题。它也使它成为跨浏览器。

// Placeholder for all browsers
app.directive("ngPlaceholder", function($log, $timeout) {
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var txt = attrs.ngPlaceholder,
                model = attrs.ngModel,
                placeholderSupport = 'placeholder' in document.createElement("input");

            //Use HTML5 placeholder attribute.
            if (placeholderSupport) {
                attrs.$set("placeholder", txt);
                return;
            }

            elem.on("focus", function(event) {
                if (elem.val() === txt) {
                    elem.val("");
                }
            });

            elem.on("blur", function(event) {
                if (elem.val() === "") {
                    elem.val(txt);
                }
            });

            scope.$watch(model, function (newValue, oldValue, scope) {
                if (newValue === undefined || newValue === "") {
                    elem.val(txt);
                    //scope.$apply(); not needed, since scope fired this event.
                }
            }, true);
        }
    }

});

于 2014-06-04T14:58:52.920 回答
1

您看到了 ngModel 问题,因此应该删除 ngPlaceholder 上的隔离范围。我意识到 sza 的解决方法有效,但我要强调的关键是 ngPlaceholder 不需要自己的范围。

例如,在这里我调整了指令并通过将创建的 txt 变量存储为它自己的局部变量来删除对范围的引用。 http://plnkr.co/edit/43z1TZHFwmgLJ9wyystD?p=preview

// Placeholder for non HTML5 browsers
app.directive("ngPlaceholder", function($log, $timeout) {
    var txt;
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var txt = attrs.ngPlaceholder;

            elem.bind("focus", function() {
                if(elem.val() === txt) {
                    elem.val("");
                }
                scope.$apply()
            })

            elem.bind("blur", function() {
                if(elem.val() === "") {
                    elem.val(txt);
                }
                scope.$apply()
            })

            // Initialise placeholder
            $timeout(function() {
                elem.val(txt)
                scope.$apply();
            })
        }
    }
})
于 2013-08-23T04:00:07.113 回答
0

IE 中的占位符支持,具有正常颜色

app.directive('placeholder',['$timeout','$window', function($timeout,$window){
    var i = document.createElement('input');
    if ('placeholder' in i) {
        return {}
    }
    return {
        link: function(scope, elm, attrs){
            var userAgent = $window.navigator.userAgent;
            if(userAgent.indexOf("MSIE 9.0") <0){
                  return;
            } 
            if (attrs.type === 'password') {
                return;
            }
            $timeout(function(){
                elm.val(attrs.placeholder).css({"color":'#ccc'});
                elm.bind('focus', function(){
                    if (elm.val() == attrs.placeholder) {
                        elm.val('').css({"color":'#555'});
                    }
                }).bind('blur', function(){
                    if (elm.val() == '') {                      
                        elm.val(attrs.placeholder).css({"color":'#ccc'});
                    }
                });
            });
        }
    }
}]);

此处的实时代码:http: //plnkr.co/edit/ev6kQ3Ks31FhqAfCMDkc

于 2015-03-09T09:38:28.870 回答