简体   繁体   中英

Angularjs - how to bind to an html element appended by javascript code

I want to bind angular event and model to an html element appended by javascript code.

My code is here. https://jsfiddle.net/hq7qk48n/13/

<div ng-app>
    <div ng-controller="MyController">
        <input type="text" ng-model="text1">
        <a href="#" ng-click="onClick()">click1</a>

        <div id="append"></div>
        <p ng-if="clickedTime1">click1 : {{ clickedTime1.toLocaleString() }}</p>
        <p ng-if="clickedTime2">click2 : {{ clickedTime2.toLocaleString() }}</p>
        <p>{{ text1 }}</p>
        <p>{{ text2 }}</p>
    </div>
</div>


function MyController($scope) {
    $scope.clickedTime1 = null;
    $scope.clickedTime2 = null;

    $scope.onClick = function () {
        var html = '<input type="text" ng-model="text2" name="text"> <a href="#" ng-click="onClick2()">click2</a>';
        $("#append").empty();
        $("#append").append(html);
        $scope.clickedTime1 = new Date();
    }

    $scope.onClick2 = function () {
        $scope.clickedTime2 = new Date();
    };
}

onClick2() doesn't work. and model "text2" is not updated. How to bind onClick2 function and text2 model?

Need to compile an html element? How?

This is a little tricky because you have an ng-click in your new element. There are 2 things we need to deal with.

  1. Correctly add the element
  2. Make your new element see the scope

First we will start with your call to the method from your element. You will need to add $event to the call

    <a href="#" ng-click="onClick($event)">click1</a>

The $event object will give you information about the calling element.

You also need to add it to your method

    $scope.onClick=function($event){

Next, your element required use of the scope so we need to turn it into an element. Otherwise just html would be fine.

    var el=angular.element('<input type="text" ng-model="text2" name="text"> <a href="#" ng-click="onClick2()"/>click2</a>');

Now you can use a little jquery but exactly on the target element the way angular would do it.

    $($event.currentTarget).empty();
    $($event.currentTarget).append(el);

At this point you would see your changes but the bindings will not work because it is not attached to the scope so we need to compile it. You will need to add the $compile server to your controller

    function MyController($scope,$compile) {

Now we can use the service to compile the new element

    $compile(el)($scope);

You should now see everything functioning the way you would expect

    function MyController($scope,$compile) {
$scope.clickedTime1 = null;
$scope.clickedTime2 = null;

$scope.onClick = function ($event) {
    var el = angular.element('<input type="text" ng-model="text2" name="text"> <a href="#" ng-click="onClick2()">click2</a>');
    $($event.currentTarget).empty();
    $($event.currentTarget).append(el);
    $compile(el)($scope);
    $scope.clickedTime1 = new Date();
}

$scope.onClick2 = function () {
    $scope.clickedTime2 = new Date();
};

}

and don't forget to add the $event to your call as well.

I did not use your exact code but I tested this as I answered to verify and it worked perfectly. It might not be best practice to work with the DOM elements in your controller but sometimes it just works. That is how you do it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM