Gavin
Gavin

Reputation: 17392

How to pass a JavaScript object already on the page in to an AngularJS template

I have a KendoUI grid on my page bound to a JavaScript array. When a row in the grid is clicked the row change event fires and I grab the object representing that row. I now want to use AngularJS's templating to bind to that model like this...

<div ng-app ng-model="currentRecord">
  {{FirstName}} - {{Surname}}
</div>

Both FirstName and Surname are properties on the object for the row. So I guess what I'm asking is how do I set the model from outside of an AngularJs controller?

I'm only just picking Angular up so what I'm asking may be a bad idea, if that's the case please let me know why.

Update

As per Pieter's answer I've tried to achieve this with "Angular Kendo"

I'm using the MVC helpers to render the grid and my code looks like this

<div ng-app="ngUsers">
    <div ng-controller="UserCtrl">
        <div class="span6">
            @(Html.Kendo().Grid(Model)
                  .Name("Grid")

                  .Columns(columns =>
                      {
                          columns.Bound(p => p.Id).Hidden(true);
                          columns.Bound(p => p.FirstName);
                          columns.Bound(p => p.LastName);
                      })
                  .Groupable()
                  .Pageable()
                  .Sortable()
                  .Scrollable()
                  .Filterable()
                  .Selectable()
                  .Events(e => e.Change("rowSelected"))
                  .DataSource(dataSource => dataSource
                                                .Ajax()
                                                .Read(read => read.Action("AjaxList", "User"))
                  )
                  )
        </div>

        <div id="results">
            {{FirstName}}   
        </div>

    </div>
</div>

What I want is for when a row is selected the firstname property in that object is shown in the results div.

My angular controller looks like this....

var ngUsers = angular.module('ngUsers', ["kendo.directives"]);

ngUsers.controller("UserCtrl", function ($scope) {
    $scope.rowSelected = function (kendoEvent) {
        var grid = kendoEvent.sender;
        var selectedRow = grid.select();
        $scope.user = selectedRow;
    }; 
});

This gives me rowSelected is not defined on the line that binds the grid change event. I assume this is because the grid can't see the rowSelected event in the angular controller?

Upvotes: 4

Views: 872

Answers (2)

Pieter Herroelen
Pieter Herroelen

Reputation: 6066

Have you looked at Angular Kendo ? Have a look at The data source example. You have to add an attribute to the div:

on-change="rowSelected(kendoEvent)"

and then you need to define a function in a controller:

$scope.rowSelected = function(kendoEvent) {
   var grid = kendoEvent.sender;
   var selectedRows = grid.select();
   ...
}

If you don't know how to define a controller and use it in your HTML, take a look at this quick video.

Upvotes: 2

Liviu T.
Liviu T.

Reputation: 23664

You need to make a couple of changes. Normally ng-model is used on inputs, but in your case we can use it as a marker to link angular world with non-angular world.

<div ng-app="plunker" ng-model="currentRecord" ng-show="currentRecord">
  {{currentRecord.FirstName}} - {{currentRecord.Surname}}
</div>

ng-model only binds to a javascript object on the current scope, so if you need to access properties from it you need to reference it directly.

Updating the model from an external(not angular) source

function myExternalFunction() {
    //external code
    // we need to get the element and wrap it in an angular element
    var $element = angular.element('[ng-model="currentRecord"]');
    var scope = $element.scope();
    //the ngModel controller will have the correct apis
    var ngModelController = $element.controller('ngModel');

    //the external data
    var model = {'FirstName' : 'John', 'Surname': 'Smith'};

    //$apply to notify angular that the models have changed from outside
    scope.$apply(function() {
      //$viewValue is only useful for inputs not divs.
      ngModelController.$viewValue = model;
      //this will actually set the value on the scope
      ngModelController.$setViewValue(model);
    });
}

Demo

Upvotes: 1

Related Questions