1

I'm trying to bind a <p> with an <input> in my application, but it is not happening. since both elements are dynamically created, I thought maybe I can use $apply, but it didn't work out. everything else is functioning as expected except for this.

My code is a bit complicated, so here is a plunker to demonstrate my situation.

HTML:

<body ng-app="tata" ng-controller="mainController">
    <div id="main">
      <div ng-controller="ctrl1">
        <button ng-click="changeCard()">Add Dynamic Bound Elements </button>
        <page id="front" size="A4"></page>
        <div id="detailsFront"></div>
      </div>
    </div>
  </body>

The elements are generated using 2 functions, on for INPUT and the other for P. Here is where the inputs are placed:

<div id="detailsFront">         
</div>

and here where the ps are placed:

<page size="A4" id="front">
</page>

The controller responsible for this view has 2 functions which are run successively in the same $scope function. Populating <p>s:

 buildPDF : function (parentElement){
      var element = angular.element(document.getElementById( parentElement ));
      ele = "<p ng-bind='id7'> Test Run </p>";
      element.append(ele);
    }

    element.append(ele);

Then the inputs:

buildPDFControllers : function (parentElement){
          var element = angular.element(document.getElementById( parentElement ));
      ele = "<label for='id7'>Some Label</label> <input name='id7' type='text' ng-model='id7'>";
      element.append(ele); 
        }
3
  • 1
    You'll need to $compile(stuff)(scope); and maybe you should use directives. And plunker would be nice. Commented Sep 6, 2015 at 11:37
  • 1
    You're right, I updated the question with a Plunker Commented Sep 6, 2015 at 13:16
  • Any help from the example, no? Commented Sep 6, 2015 at 17:22

2 Answers 2

5

You must always $compile new elements.

HTML

<body ng-app="tata">
  <div ng-controller="ctrl1">
    <page id="front"></page>
  </div>
</body>

JavaScript

var app = angular.module('tata', [])

  .controller('ctrl1', function ($scope, $compile) {
    $scope.id = 'some id here';

    var element = angular.element(document.getElementById('front'));
    var p = '<p ng-bind="id">Test Run</p>'; // <- will be bound/replaced with $scope.id
    element.append(p);

    $compile(element.contents())($scope);
  }); 

But maybe you'd be better off using directives instead? Consider:

HTML template

<body ng-app="cards" ng-controller="Ctrl">
  <button ng-click="addCard()">Add Card</button>
  <div ng-repeat="card in cards">
    <card ng-model="card"></card>  
  </div>
</body>

JavaScript

angular.module('cards',[])

  .controller('Ctrl', function($scope) {
    $scope.cards = [];

    $scope.addCard = function() {
      var next = $scope.cards.length + 1; 
      $scope.cards.push({id: next, label: next});
    };
  })

  .directive('card', function() {
    return {
      restrict: 'E',
      require: 'ngModel',
      scope: {
        ngModel: '='
      },
      template: '<p>Directive model: {{ ngModel | json }}</p>' +
                '<label>Label: </label>' + 
                '<input name="{{ ngMode.id }}" ' + 
                '       type="text" ' +
                '       ng-model="ngModel.label">',
      link: function(scope) {
      }
    };
  });

imgur

Sign up to request clarification or add additional context in comments.

Comments

0

You'd probably be better off using directives for this - and you might not even need to roll your own. Have a look at ng-include: it lets you switch which HTML template to use based on a variable in your scope. Something like:

inputText-view.html:

<p ng-style="style">{{value.content}}</p>

page.html:

<page size="A4" id="front" style="position: absolute, top:0px, left:0px">
    <ng-include
        ng-repeat="value in values"
        src="value.type + '-view.html'"></ng-include>
</page>

See here for a demo.

Here's another demo based on your plunk.

10 Comments

@z0r thank you it seems interesting, i didn't know I could use ng-include. Which is more preferable, ng-view or ng-include ?
@MikkoViitala Fair enough, I was just going by the docs' "Typically, you don't use ngBind directly". But you're right; I'll remove that recommendation.
I updated the question with a plunker, if you can find a solution for that i'll mark it as an accepted answer. + i'll look into the ng-include
ng-view is for changing the active controller and template based on the route. In this case you need ng-include.
can you explain further? what is so special about this situation ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.