-1

2 options: what is better for performance and watchers using, now I am using the first option and I would like to improve performance

the object today looks like:

message = {
   message : X, 
}

and I would like to do somthing like :

obj = {
   text : text,
   icon: "src.png"
   status: X,
   class : "className",
   color: "color_code_like_#ffff"
}

1 :

<div ng-if="message.message == 0" class="classA" style="">
  <span class="same"><img class="sameClass" ng-src="a.gif"></span>
  <span class="status-text a_with_animation" style="color:red;">textA</span>
</div>
<div ng-if="message.message == 1" class="classB" style="">
  <span class="same"><img class="sameClass" ng-src="b.png"></span>
  <span class="status-text" style="color:blue;">textB</span>
</div>1
<div ng-if="message.message == 2" class="classC" style="">
  <span class="same"><img class="sameClass" ng-src="c.png"></span>
  <span class="status-text" style="color:black;">TextC</span>
</div>

option 2

<div class="{{obj.class}}" style="">
  <span class="same"><img class="sameClass" ng-src="{{obj.class}}"></span>
  <span class="status-text {{obj.animation}" style="color:red;">
   {{obj.text}}</span>
</div>

also all the data here is two way binding

Tuz
  • 1,810
  • 5
  • 29
  • 58
  • why not use `ng-class`? – Aleksey Solovey Feb 14 '18 at 13:10
  • @AlekseySolovey . yes it is an option . I am asking about performance and watchers – Tuz Feb 14 '18 at 13:16
  • 1
    `ng-if` destroys DOM (slow), two-way binding (`{{ __ }}`) adds a watcher. So maybe it's better to use `ng-show` or (if `message.message` is not changing and is pre-defined) a one-way data-binding - `{{:: __ }}` – Aleksey Solovey Feb 14 '18 at 13:27
  • The `{{}}` is much slower. This ng-bind is a directive and will place a watcher on the passed variable. So the ng-bind will only apply, when the passed value does actually change .The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not necessary. – super cool Feb 14 '18 at 13:38
  • @AlekseySolovey I need two-way binding here – Tuz Feb 14 '18 at 13:56
  • @AlekseySolovey is there an option to build the html and return it from the model ? instead two way binding – Tuz Feb 14 '18 at 13:58
  • @Guz possibly some kind of partial/template with `ng-include` or similar (directive _with isolated scope_) – Aleksey Solovey Feb 14 '18 at 13:59
  • @AlekseySolovey do you have any example of that ? and what do you think should I choose , option 1 or 2 ? i have objects , each object include status object with that details – Tuz Feb 14 '18 at 14:26

1 Answers1

1

Not really pretty but I made an example of how you could populate your data with ng-include template. Here is a demo:

<!DOCTYPE html>
<html ng-app="myApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

<body>
  <div ng-controller="myCtrl">

    <select ng-model="message" ng-change="change()" ng-options="x.message for x in messages">
</select>
    <br>
    ngInclude: <div ng-include="'abc.html'"></div>
    Directive: <div temp-directive></div>

    <!-- A separate file for the template -->
    <script type="text/ng-template" id="abc.html">
      <div class="{{obj.class}}" style="">
        <span class="same"><img class="sameClass" ng-src="{{obj.icon}}"></span>
        <span class="status-text {{obj.animation}}" ng-style="obj.style">
   {{obj.text}}</span>
      </div>
    </script>

  </div>

  <script>
    var app = angular.module('myApp', []);
    app.directive("tempDirective", function() {
        return {
            template : "<div class='{{obj.class}}' style=''><span class='same'><img class='sameClass' ng-src='{{obj.icon}}'></span><span class='status-text {{obj.animation}}' ng-style='obj.style'> {{obj.text}}</span></div>"
        };
    });

    app.controller('myCtrl', function($scope) {

      $scope.messages = [{
        "message": 0
      }, {
        "message": 1
      }, {
        "message": 2
      }];

      $scope.message = $scope.messages[0]; // initialise

      $scope.objects = [{
        "text": "Message - 0",
        "icon": "a.gif",
        "animation": "a_with_animation",
        "class": "classA",
        "style": {
          "color": "#00aaaa"
        }
      }, {
        "text": "Message - 1",
        "icon": "b.png",
        "animation": "",
        "class": "classB",
        "style": {
          "color": "#aa00aa"
        }
      }, {
        "text": "Message - 2",
        "icon": "c.png",
        "animation": "",
        "class": "classC",
        "style": {
          "color": "#aaaa00"
        }
      }];

      $scope.obj = $scope.objects[0]; // initialise

      $scope.change = function() { // changing the template data
        $scope.obj = $scope.objects[$scope.message.message];
      }

    });
  </script>

</body>

</html>

[Note]: it is best to replace ng-include with a component / directive with their template (not templateUrl) for performance improvement, since it is asynchronous and takes time to load the HTML

Aleksey Solovey
  • 4,153
  • 3
  • 15
  • 34
  • Thanks a lot , How can I do that in the directive ? I mean when there is a change an I need to change the html . How can I do that with directive from other directive for example ? – Tuz Feb 14 '18 at 15:22
  • I dont want to use ng-include, look here : http://www.codelord.net/2016/11/17/avoiding-ng-include-for-elegenace-and-performance/ – Tuz Feb 14 '18 at 15:24
  • @Guz yeah, I'm aware of potential performance issues, but I just don't use directives often. You would simply need a `template` (as a string), link scoped object (array), restrict and bind it correctly, and then call a [directive function from your controller](https://stackoverflow.com/questions/16881478/how-to-call-a-method-defined-in-an-angularjs-directive) to change the template data (just like in my example with ` – Aleksey Solovey Feb 14 '18 at 15:28
  • @Guz I tried adding a simple directive _just_ for the template alone. Check the updated code – Aleksey Solovey Feb 14 '18 at 15:35
  • is there any difference if it is in templateURL instead of a template? and this is totally better than use ng-if for each status? like I have 7 statuses . so it is mean option 2 it better but event though I did not saw wathcer imporvment ,because I a trying to reduce the watcher here – Tuz Feb 14 '18 at 15:58
  • @Guz `templateUrl` loads data asynchronously (and saves it in _template cache_), so it adds a delay. You can't easily reduce the number of watchers. But their number decreases with a template or `ng-if` (which _removes_ any other content that doesn't need to be rendered) – Aleksey Solovey Feb 14 '18 at 16:17
  • ng-if add another wathcer no ? because I have 6 ng-if for 6 statuses and how can I easily reduce the watcher if it is two-way binding . . thanks because that logic also exist in ng-repeat because I need that status in different location of the page. (for example I pass the object in 3 directives) – Tuz Feb 14 '18 at 16:30
  • @Guz in that case `ng-switch` would be better (instead of multiple `ng-if`) – Aleksey Solovey Feb 14 '18 at 17:00