Philip Andersson
Philip Andersson

Reputation: 100

Change root scopes parameter inside directive link

I have an issue when trying pushing a new object into the attachments parameter and. It is not updated in the ng-repeat inside template.html

AS you can see i do a array.push in the success-function of dropzone and it gets pushed into the array but the list is not updated.

Thanks in advance for any help.

directive.js

(function() {
  "use strict";
  module.exports = attachments;

  function attachments($auth) {

    var _token = "Bearer" + " " + $auth.getToken();

    return {
      restrict: 'EA',
      scope: {
          objectType: '@',
          objectId: '=',
          attachments: '='
      },
      transclude: true,
      templateUrl: 'template.html',
      replace: true,
      link: function(scope, element, attrs) {

          element.find(".drop").first().dropzone({
              url: '<url>',
              multiple: true,
              uploadMultiple: false,
              headers: {
                  "Authorization": _token
              },
              init: function(){
                  this.on("success", function (file) {
                      this.removeAllFiles();
                  });
              },
              success: function(file, response){
                  scope.attachments.push(response);
              },
              sending: function(file, xhr, data){
                  data.append("object_id", scope.objectId);
                  data.append("object_type", attrs.objectType);
              }
          });
      }
    }

  }

  attachments.$inject = ['$auth'];

})();

template.html

<div class="cirons-upload">
    <div class="drop"></div>
    <ul class="list" id="preview_list">

    </ul>
    <ul class="list">
        <li ng-repeat="file in attachments">
            <a href="#">{{file.file_name}}</a>
        </li>
    </ul>
</div>

page.html The object invoice has id as integer and attachments as an array.

<cirons-attachments
    object-id="invoice.id"
    object-type="Invoice"
    attachments="invoice.attachments"
></cirons-attachments>

Upvotes: 1

Views: 35

Answers (1)

Cyril Gandon
Cyril Gandon

Reputation: 17048

Using a third party library with angular need some plumbery.

Angular don't detect the changes on attachments, because the change detection algorithm is launch on mouse events, ajax callback, etc... So you need to manually launch a digest cycle.

One usual way is to wrap the modification code into a $timeout.

Try that:

(function() {
  "use strict";
  module.exports = attachments;

  function attachments($auth, $timeout) {

    var _token = "Bearer" + " " + $auth.getToken();

    return {
      restrict: 'EA',
      scope: {
          objectType: '@',
          objectId: '=',
          attachments: '='
      },
      transclude: true,
      templateUrl: 'template.html',
      replace: true,
      link: function(scope, element, attrs) {

          element.find(".drop").first().dropzone({
              url: '<url>',
              multiple: true,
              uploadMultiple: false,
              headers: {
                  "Authorization": _token
              },
              init: function(){
                  this.on("success", function (file) {
                      this.removeAllFiles();
                  });
              },
              success: function(file, response){
                  $timeout(function () { 
                      scope.attachments.push(response);
                  }, 0)
              },
              sending: function(file, xhr, data){
                  data.append("object_id", scope.objectId);
                  data.append("object_type", attrs.objectType);
              }
          });
      }
    }

  }

  attachments.$inject = ['$auth', $timeout'];

})();

Upvotes: 1

Related Questions