0

I have directive 'copyPaste' which copies element value to the element specified in 'destination' attribute.

// html code
<div ng-app='app'>
 <div ng-controller="mainController">
 <input type='text' ng-model='firstInput' copy-paste destination='secondInput'>
 <input type='text' ng-model='secondInput'>

 <!-- following does not work -->

   <input type='text' ng-model='param.firstInput' copy-paste destination='param.secondInput'>
 <input type='text' ng-model='param.secondInput'>

 </div>
</div>


//directive code

module.directive('copyPaste',['$rootScope',function($rootScope){
 return {
 restrict:'A',
 link:function(scope,element,attrs,ctrl){
 var destination=attrs.destination;
 scope.$watch(attrs.ngModel, function (v) {
            scope[destination]=v 
            });
 }
 }
}])

//controller

    module.controller('mainController',['$scope',function($scope){
     $scope.firstInput='hello'
    }]);

Above code works if I pass simple variable. If I pass object , array it does not work . How can I pass array and objects to directive as string then use as variables. I dont want to run directive in isolate scope, in isolate scope I need to call $scope.$apply to update binding so trying to avoid isolate scope.

JsFiddle

3 Answers 3

1

Ok so I got this to work. This should do it see -> plunk:

basically im traversing your scope tree to find the object for which you want to set the value. Not the prettiest but it gets the job done

var module = angular.module('app', []);
module.directive('copyPaste', ['$rootScope', function($rootScope) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs, ctrl) {
      var destination = attrs.destination;


scope.$watch(attrs.ngModel, function(v) {
        var splitted = destination.split('.');
        if (splitted.length > 1) {
          var value = null;
          var lastKey = "";
          for (var i = 0; i < splitted.length; i++) {
          if(value == null) {
          value = scope[splitted[i]];
          } else {
          if(value[typeof splitted[i] == 'Object']) {
          value = value[splitted[i]];
          } else {
            lastKey = splitted[i];
          }

                    }
          }
          value[lastKey] = v;

                } else {
        scope[destination] = v;
        }
            });
    }
  }
}])

module.controller('mainController', ['$scope', function($scope) {
  $scope.firstInput = 'hello';
  $scope.secondInput = "";
  $scope.param = {};
  $scope.param.secondInput = "";
  $scope.param.firstInput = "Again";
}]);
Sign up to request clarification or add additional context in comments.

Comments

0

You can use JSON.stringify for convert value to a JSON string, and then later use JSON.parse which turns a string of JSON text into a Javascript object

Comments

0

I think you should use an event instead of $watch, it would be more performant. Have a look at ngChange (https://docs.angularjs.org/api/ng/directive/ngChange)


I think the problem could be due to $watch that is not checking your variable properly.

You could try to set the objectEquality boolean to true (doc here https://docs.angularjs.org/api/ng/type/$rootScope.Scope )

 scope.$watch(attrs.ngModel, function (v) {
                scope[destination]=v 
            }, true); // <-- deep object check

1 Comment

even with object/arrays?

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.