Angular How to use jQuery to add ngModel and ngBind to custom directive elements?


[Info]
I am trying to implement some custom angular directives that encapsulate all the JS necessary for them to work.
The directives do not know what they will display, and where to store any input value coming from the user. This information will be obtained from the attributes of the directive.
My directives will use the parent scope and will not create their own.

[Problem] Since the directive does not know where to display ng-model and ng-bind in $ scope, my approach is to read the properties of the directive, determine what attributes ng-model and ng-bing should be, and set them to relevant items, however this does not work.
I believe this is due to my lack of knowledge, so I ask here - if my approach is okay ?; Is it possible to set ngModel and ngBind in this way ?; What am I doing wrong?

[My directive code]

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


[Result] As a result, I see on the HTML page where ng-model and ng-bind are bound in the right place, I have scope [scopeValueName] and scope [elementIdentifier] in the area that Batarang provides, but I do not see them on the screen as values.

Has anyone resolved a similar problem?

!

[] , , . !

HTML:

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

angular jo:

<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 = default. .

+4
3

, - :

<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>

angular , :

  • , , transclude

  • (, , span) tElement , html

: Angularjs: transclude

, ng-model .., , ( "link()" ):

.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) {}
    }
}

- , - , - .

EDIT:

: 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

+1

, , , - , , .

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, , .

0

There is a much simpler way to do this: (see jsfiddle at http://jsfiddle.net/j55B8/17/ )

Code for directive:

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}}
0
source

Source: https://habr.com/ru/post/1542913/


All Articles