How to data-bind an mvc partial view using angularjs directives

I have the following angularjs directive:

app.directive("partnersInfoView", function ($http) {
    return {
        restrict: 'A',
        link: function ($scope, element) {
            $http.get("/home/PartnerInfoTab") // immediately call to retrieve partial
              .success(function (data) {
                  element.html(data);  // replace insides of this element with response
              });
        }
    };
});

which basically goes to an MVC controller and returns a partial view

public ActionResult PartnerInfoTab()
{
    return PartialView("../ManagePartners/PartnerInfoTab");
}

in the parent view i have the following declaration:

<div id="genericController" ng-controller="GenericController">
    <div partners-info-view></div>
</div> 

that is making use of the angular directive to render the partial view, so far everything works great. Inside of my angular genericController i have a scope variable:

$scope.Data = data;

where data it's a json object that comes as response from a Rest Service

Json Response e.g.

{[
    {"firstName":"John", "lastName":"Doe"},
    {"firstName":"Anna", "lastName":"Smith"},
    {"firstName":"Peter", "lastName":"Jones"}
]}

The issue im having is that i cannot bind the $scope.Data variable in the directive template:

 <div id="PartnerInfoTab">
    <div class="form-group">
        <label class="col-md-2 control-label">Name</label>
        <div class="col-md-8">
            <input id="txt_name" class="form-control" type="text" ng-model="Data.firstName">
        </div>
    </div>
</div>

My question is, How do you pass the parent scope to the angular directive in order to be able to data-bind the elements in the partial view. What am i missing ??

Thanks in advance.

Upvotes: 4

Views: 12201

Answers (2)

jad-panda
jad-panda

Reputation: 2547

I don't see any use of fetching template manually using $http.get and then inserting it to DOM. you can simply give templateUrl value in directive configuration and angular will fetch the template and compile it for you.

app.directive("partnersInfoView", function ($http) {
     return {
           restrict: 'A',
           templateUrl: '/home/PartnerInfoTab',
           link: function (scope, element, attr) {
               // Do linking
           }
     };
});

And, your partnersInfoView does not create isolated scope. so, you can access values of partnersInfoView's parent scope value. see the below snippet.

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

app.run(function($templateCache) {
  // Simulating the fetching of /home/PartnerInfoTab template
  var template = '<div id="PartnerInfoTab">' +
    '<div class="form-group">' +
    '<label class="col-md-2 control-label">Name</label>' +
    '<div class="col-md-8">' +
    '<input id="txt_name" class="form-control" type="text" ng-model="Data[0].firstName">' +
    '<input id="txt_name" class="form-control" type="text" ng-model="Data[1].firstName">' +
    '<input id="txt_name" class="form-control" type="text" ng-model="Data[2].firstName">' +
    '</div>' +
    '</div>' +
    '</div>';

  $templateCache.put('/home/PartnerInfoTab', template);
});

app.controller('GenericController', function($scope) {
  $scope.Data = [{
    "firstName": "John",
    "lastName": "Doe"
  }, {
    "firstName": "Anna",
    "lastName": "Smith"
  }, {
    "firstName": "Peter",
    "lastName": "Jones"
  }];
});

app.directive("partnersInfoView", function($http) {
  return {
    restrict: 'A',
    templateUrl: "/home/PartnerInfoTab",
    link: function($scope, element) {
      // linking
    }
  };

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div id="genericController" ng-controller="GenericController">
    <div partners-info-view></div>
  </div>
</div>

Upvotes: 2

Bartosz Gościński
Bartosz Gościński

Reputation: 1580

What you are missing is probably compilation of your template. What you have to do is use $compile service in your success handler:

.success(function (data) {
    var linkingFunction = $compile(data); // compile template
    var linkedElement = linkingFunction($scope); // and link it with your scope

    element.append(linkedElement);
});

Upvotes: 0

Related Questions