1

A bit confused with binding...

How to properly bind values from input fields to textarea?

 app.controller('MainCtrl', function($scope) {
  $scope.hello = 'Hello';
  $scope.world = 'World!'
  //this template comes from json
  $scope.fromjson = "{{hello}} {{world}} and have a good time";
  //this template comes from json
});

And a simple body:

 <body ng-controller="MainCtrl">
  <input ng-model="hello">
  <input ng-model="world">
  <helloworld></helloworld>
  </body>

A have to edit my miserable example because your kindly answers didn't solve my problem.

I had plenty of unique texts - letter templates in which some fields should be filled by user. There are ten fields occuring conditionally depending of text selected.

text1: "Blah, blah {{field.first}}.blah {{filed.second}}" 
text2: "{{field.third}} blah, blah {{field.first}}"
text3: "Blah, blah {{field.fourth}}"
and so on...

Texts are stored in database and obtained through JSON

 function(textid) {
    $http.get('json/json.php',
    {    params: { id: textid } }).
    success(function(data, status, headers, config) {
    $scope.SelectedText = data;
    })
    };

I organized it in one form with all ten input fields, visible depending of selected text. Completed/filled template should be visible in textarea at the bottom of form to be copied to another place.

  • Should I change the way I store the templates?
  • or back to question is there any other way the fields could be inserted into view ?
0

4 Answers 4

2

I think what you need is $interpolate service and $scope.$watch take a look at this jsfiddle :

http://jsfiddle.net/michal_taborowski/6u45asg9/

app.controller('MainCtrl', function($scope,$interpolate) {
  $scope.hello = 'Hello';
  $scope.world = 'World!';
  //this template comes from json
  $scope.template = " {{hello}} {{world}} and have a good time";
  //this template comes from json   

  var updateTemplate = function(oldVal,newVal,scope){
     scope.fromjson = $interpolate(scope.template)(scope);
  }

  $scope.$watch('hello', updateTemplate );
  $scope.$watch('world', updateTemplate );

});

Of course you should move $watch to link function in your directive and pass hello and world as scope variable to this directive - this is just a quick example how you can do it.

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

Comments

2

I think that what you want is this:

app.controller('MainCtrl', function($scope) {
  $scope.hello = 'Hello';
  $scope.world = 'World!'
  //this template comes from json
  $scope.fromjson = function(){
     return $scope.hello + " " + $scope.world + " and have a good time";
  };
});

app.directive('helloworld', function() {
  return {
    restrict: 'E',
    template: '<textarea>{{fromjson()}}</textarea>'
  };
});

Example here: http://plnkr.co/edit/8YrIjeyt9Xdj2Cf7Izr5?p=preview

The problem with your code is that when you declare $scope.fromjson = "{{hello}} {{world}} and have a good time" you are not binding anything, you are just assiging that string to the fromjson property.

EDIT:

As HeberLZ pointed out in the comment bellow, it would be much more efficient to do this instead:

app.controller('MainCtrl', function($scope) {
  $scope.hello = 'Hello';
  $scope.world = 'World!'
});

app.directive('helloworld', function() {
  return {
    restrict: 'E',
    template: '<textarea>{{ hello + " " + world + " and have a good time"}}</textarea>'
  };
});

3 Comments

The first one won't update after you change hello and/or world. This second one on the other hand will update but will also introduce a leak in performance because of how the AngularJS framework works· People should NEVER execute functions inside interpolations {{ }} as Angular doesnt know in each digest cicle if it has changed and will reexecute and reexecute the function many times
@HeberLZ I just made an update based on your comment, thanks!
I like this one more than my own answer, i didn't pull the string about them having scope inheritance because of not defining the scope attribute inside the directive. Good catch
1

One way would be something like this:

Controller:

app.controller('MainCtrl', function($scope) {
  $scope.hello = 'Hello';
  $scope.world = 'World!'
});

Directive:

app.directive('helloworld', function($http) {
  return {
    restrict: 'E',
    scope: {
      'hello': '=',
      'world': '='
    },
    link: function(scope){
      scope.jsonFromServer = '';
      $http.get('someUrl').then(function(response){
        scope.jsonFromServer = response.data;
      });

      var updateFromjson = function(){
        scope.fromjson = scope.hello + ' ' + scope.world + ' ' + scope.jsonFromServer;
      }

      scope.$watch('hello', updateFromjson);
      scope.$watch('world', updateFromjson);
    }
    template: '<textarea>{{fromjson}}</textarea>'
  };
});

Body:

<body ng-controller="MainCtrl">
  <input ng-model="hello">
  <input ng-model="world">
  <helloworld hello="hello" world="world"></helloworld>
</body>

Comments

0
app.controller('MainCtrl', function($scope) {
  $scope.hello = 'Hello';
  $scope.world = 'World!'
  //this template comes from json
  $scope.aDiffFunc = function() {
      return $scope.hello + " " + $scope.world + " and have a good time";
  };
  //this template comes from json

});

app.directive('helloworld', function() {
  return {
    restrict: 'E',
    template: '<textarea>{{aDiffFunc()}}</textarea>'
  };
});

this should be it??

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

2 Comments

Yep, That would work too, but it won't keep updating if you make changes to "$scope.hello" or "$scope.world", that's why I put it in a function ;)
don't put functions inside interpolations, they make the function execute an enormous amount of time on big applications because of the quantity of digest cycles

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.