Angular指令-如何使用JQuery将ngModel和ngBind添加到自定义指令元素中

Angular directives - How to use JQuery to add ngModel and ngBind to custom directive elements?

本文关键字:指令 添加 ngBind 元素 自定义 ngModel 何使用 JQuery Angular      更新时间:2023-09-26


[信息]
我试图实现的是实现一些自定义的angular指令,这些指令将封装它们工作所需的所有JS
指令不知道它们将显示什么以及将来自用户的任何输入值存储在哪里。这些信息将来自指令的属性
我的指令将使用父作用域,而不会创建自己的作用域。

[问题]由于指令不知道在$scope中的何处映射ng模型和ng绑定,我的方法是读取指令的属性,确定ng模型和ng-bing属性应该是什么,并将它们设置为相应的元素。然而,这并不奏效
我认为这是由于我缺乏知识,所以我在这里问——我的方法是否可以?;可以用这种方式设置ngModel和ngBind吗?;我做错了什么?。

[我的指令代码]

var directives = angular.module('test.directives', []);
directives.directive("labeledInput", function() {
return {
    restrict: 'E',
    scope: false,
    template: "<div>" +
                "<span class='label'></span>" +
                "<input class='input' type='text'></input>" +
              "</div>",
    link: function(scope, element) {
        var elementIdentifier = angular.element(element[0]).attr("idntfr");
        var elementClass = angular.element(element[0]).attr("element-class");
        var scopeValueName = angular.element(element[0]).attr("value-name");
        var defaultValue = angular.element(element[0]).attr("default-value");
        var elementLabel = angular.element(element[0]).attr("label");
        scope[scopeValueName] = defaultValue;
        scope[elementIdentifier] = elementLabel;
        $(angular.element(element[0]).children()[0]).attr('id', elementIdentifier);
        $(angular.element(element[0]).children()[0]).addClass(elementClass);
        $(angular.element(element[0]).children().children()[1]).attr('ng-model', scopeValueName);
        $(angular.element(element[0]).children().children()[0]).attr('ng-bind', elementIdentifier);
    }
};
});


[结果]因此,我在HTML页面中看到,ng模型和ng绑定绑定在正确的位置,我在Batarang提供的作用域中有scope[scopeValueName]scope[elementIdentifier],但我在屏幕上看不到它们是值。

有人解决过类似的问题吗?

谢谢你抽出时间!

[编辑]很抱歉,我的问题似乎没有被理解,我会补充一些细节!

以下是我的指令的HTML用法示例:

<labeled-input
    idntfr='id001'
    element-class='someClass'
    value-name='person_name'
    default-value='default'
    label='Person Name:'
>
</labeled-input> 

在角度解析我的指令并完成它的任务后,我在浏览器中拥有的是:

<div id="effect_dt" class="someClass">
    <span class="label" ng-bind="id001"></span>
    <input class="input" type="text" ng-model="person_name">
</div>

我的控制器作用域中有-$scope.id001="人名:"和$scope.Person_Name=默认值。但是,这些值根本没有显示在页面上。

如果我正确理解你,你想做这样的东西:

<labeledInput>model-name and/or field name</labeledInput>

并将其转换为类似的内容

<div>
    <span class='label' ng-bind="mode-name.field-name"></span>
    <input class='input' type='text'></input>
</div>

无论如何,你必须阅读更多关于指令中角度编译的内容:

  • 要获得对指令原始内容的任何访问,如属性或内部内容,您需要使用transclude

  • 要访问模板内容(例如,在您的情况下,让我们说"span"元素(,您必须在compile方法中调用tElement参数,因为它将保存来自模板的html

以下是一些很好的例子:Angularjs:transclude指令模板

所有这些操作,如添加ng模型属性指令等。你应该在指令编译之前添加,为此你必须使用编译块(代替你的"链接(("块(:

.compile = function compile(tElement, tAttrs) {
    //here add some code eg append ng-model attribute etc.
    return {
    pre: function preLink(scope, iElement, iAttrs) {},
        post: function postLink(scope, iElement, iAttrs) {}
    }
}

最后一部分是控制器范围,最简单的方法就是在模板中添加控制器,这样就不会丢失任何范围。

编辑:

在阅读了你更新的问题后,我会尝试一下:p

app.directive('labeledInput', function($compile) {
  var directive = {};
  directive.transclude = true;
  directive.restrict =  'E';
  directive.template =  "<div>" +
                "<span class='label' ></span><br/>" +
                "<input class='input' type='text' ></input>" +
              "</div>";
  directive.compile =  function(cElem, cAttrs) {
    var scope=angular.element(cElem).scope();
    console.log(scope);
    var elementIdentifier = angular.element(cElem[0]).attr("idntfr");
    var elementClass = angular.element(cElem[0]).attr("element-class");
    var scopeValueName = angular.element(cElem[0]).attr("value-name");
    var defaultValue = angular.element(cElem[0]).attr("default-value");
    var elementLabel = angular.element(cElem[0]).attr("label");
     $(cElem[0]).find("div").attr('id', elementIdentifier).addClass(elementClass);
     $(cElem[0]).find("div span").attr('ng-bind', scopeValueName);
     $(cElem[0]).find("div input").attr('ng-model', elementIdentifier);
     return {
            pre: function preLink(scope, iElement, iAttrs) {
            scope[scopeValueName] = defaultValue;
      scope[elementIdentifier] = elementLabel;
            }
     };
    };
  return directive;
});

http://plnkr.co/edit/ImJmTHP3eQCzPaKfRTS4?p=preview

http://plnkr.co/edit/KIcfwsUGfCeg1UtioFv0?p=preview

我不确定这是否正确,但我想你想构建某种通用指令,其行为源自父作用域并绑定到它的模板,在本例中是输入字段。

你可以在labeledInput指令上创建一个隔离作用域,比如:

scope: {
   doSomething:'&' 
}

它的模板将变成:-

template: "<div>" +
            "<span class='label'></span>" +
            "<input class='input' type='text' ng-change="doSomething()"></input>" +
          "</div>",

你的html将是:-

    <labeledInput doSomething="someFunctionOnController()"></labeledInput>

所以,在控制器的作用域中定义的someFunctionOnController将在输入字段更改时被调用。

有一种更简单的方法可以做到这一点:(请参阅http://jsfiddle.net/j55B8/17/)

指令代码:

var directives = angular.module('test.directives', []);
directives.directive("labeledInput", function() 
    return {
        restrict : "E",
        replace : true,
        scope : {
            "idntfr" : "@",
            "elementClass" : "@",
            "valueName" : "=",
            "defaultValue": "@",
            "label" : "@"
        },
        template : "<div id='{{idntfr}}' class='{{elementClass}}' ng-init='valueName=defaultValue'>" +  
                       "<span class='label' ng-bind='label'></span>" +
                       "<input class='input' type='text' ng-model='valueName'></input>" +
                   "</div>"
    }
});

HTML

<labeled-input 
    idntfr='id001' 
    element-class='someClass' 
    value-name='person_name' 
    default-value='default name' 
    label='Person Name: '>
</labeled-input>
The value typed in the above text box is {{person_name}}