Angular.js Error: matrix not invertible - angularjs

I am using AngularJS with ThreeJS, trying to make some 3D interactive graphics in my web app.The ThreeJS part successfully shows up and works as expected but AngularJS seems to be not working.
In my index.html, I have:
<html ng-app="plantApp">
<body ng-controller="AppCtrl">
<plant-canvas></plant-canvas>
<div>{{data}}</div>
</body>
</html>
Here plant-canvas is a custom directive and its definition is:
angular.module("plantApp")
.directive("plantCanvas", function() {
return {
restrict: "E",
templateUrl: 'partials/canvas.html',
controller: 'canvasCtrl',
scope: {
data: '='
}
};
});
canvasCtrl is a controller only for canvas manipulation and canvas.html is the partial html file for canvas stuff. I am now trying to display a variable called test and the graphics. So in the partial html file, I have
<div>{{test}}</div>
<div id="container"></div>
Where the container is used by ThreeJS for drawing. In canvasCtrl, I have:
angular.module("plantApp")
.controller("canvasCtrl",function($scope){
$scope.test = "This is a test";
//ThreeJS code for drawing here
});
All the functions for graphics are also in canvasCtrl. When I run the website, I have
{{test}}
showing up, followed by the graphics part. I have no clue how to solve this since the error seems to be generated by three.js but caught by AngularJS as well. Angular does not manipulate graphics directly but the script is written in the controller. If I move "" to index.html and move the graphics part of code to index.html within a script tag, then AngularJS will work fine - "This is a test" will show up. What should I do? Is there a better way to mix ThreeJs with AngularJS?
I think a way to solve this problem is to let angular ignore this error and continues its work, is it possible to do this?

Related

What to Bundle in VS15 MVC Project Using AngularJS

I'm experimenting with using angularjs in a .NET MVC environment. I have placed the usual Razor statement #Scripts.Render("~/bundles/angular") in the head of my _layout.cshtml, and yes it does produce the desired element, as I see when I do a 'View Page Source' on the resultant page. The tag I'm trying to use angularjs on is simply a run-of-the-mill tag. I don't see any errors, and everything else is working fine, but it doesn't appear that the browser is calling the controller before it renders my element.
When does the browser execute the controller code associated with the ng-controller attribute? Does it matter where I place the definition of the controller? I'm simply using the usual angular.module method inside a element to define it, like so:
angular.module('app',[]).controller("FredCtrl",
function($scope){ $scope.message = "- - -"; })
Yet $scope.message seems to be empty. Any suggestions?
Do I need to bundle something else other than just ~/Scripts/angular.js for something so simple?
Thanks for any assistance.
No, the console tab in the Firefox F12 tools doesn't show any errors. Here is the simple h2 element I'm trying to apply angularjs to
<h2 ng-constroller="FredCtrl">Getting started {{message}}</h2>
<script type="text/javascript">
angular.module('app',[]).controller("FredCtrl",
function($scope){ $scope.message = "- - - -"; })
</script>
and yes I do have the ng-app attribute set in my body tag, like so:
<body ng-app="app">
Oh, and I tried it in Chrome as well, with the same result. Everything seems to be working just fine. No errors show up in the Console tab for Chrome as well. I just don't see my $scope.message show up in the display.

injecting html content in empty template

I retrieve the code of an HTML page from a server thanks to a rest service and I want integrate the html code into an empty template
.controller('TestController', ['$scope' ,'$rootScope' , '$sce' , function ($scope ,$rootScope,$sce) {
var restHtml =$rootScope.test; //contains <div>Test</div>
$scope.showHtml= $sce.trustAsHtml(restHtml );
}]);
The template
<div ng-bind-html="showHtml"></div> <!-- didn't work and i want a solution without integrate my html code into a existing div -->
Thank you
Ideally DOM manipulations should not happen in the controller, directives should be used for them.
To answer your question, you could compile the html into your tag. Get the html, find the element you want to insert the html in and use compile to do it. A good example of compile.

variable templateURL in angular

I've only been working with angular for 2 weeks so fairly new to the framework.
I'm making an app that shows data through charts, and i want the data to be viewable in different chart types. The idea is that you can click a button and swap the chart type.
The way i've been doing this is by rendering the chart through a directive using templateURL. Unfortunatly i've been unable to make the templateURL variable. I've tried different things and this is how it looks atm:
main.html:
<chart charttype="{{chartType}}"></chart>
directive:
.directive("chart", function () {
return {
restrict: 'E',
templateUrl: function (element, attrs) {
return 'views/partials/' + attrs.charttype + '.html';
}
}
Controller:
$scope.chartType = "lineChart";
$scope.ChangeChart = function (chartType) {
$scope.chartType = chartType;
}
The code is supposed to render 3 different html files (lineChart.html, barChart.html & pieChart.html). however the {{chartType}} is simply parsed as a string
It works when i use:
<chart charttype="lineChart"></chart>
For whatever reason i can't get the charttype attribute to become variable.
I also realize this might be more of a rails way of fixing an angular problem (i'm used to rendering partials). So maybe this is not the way to do this in angular. I've thought about other ways to do this like hide/show the charts but this just seems ugly to me. I'm up for any suggestions though.
update 1:
so i'm trying to render it via ng-include in all the ways i can think of but it keeps giving me errors or doesn't show anything at all.
i've also tried putting the ng-include directly into my html file
<div ng-include="views/partials/lineChart.html"></div>
However in my browser i see it just comments this line out.
update 2:
I couldn't get ng-include to work with a variable template. So i've decided to solve the problem by removing the templates and using ng-hide in my html file instead.
Once the template url is set, it is not called again. Use ng-include with variable template
Something like
template: "<div ng-include=\"'views/partials/' + charttype + '.html'\"></div>"
Directive templateUrl parameter can't get variable value as argument, just static text. if you want, i can show solution with ng-include directive in directive template parameter.

What is tool exists in AngularJS for template?

For example, I have HTML code in variable JS:
var template = '<div>%name%</div>';
How easy to replcae %name% on text in template? What is tools provided in Angular JS for this?
What you're trying to do is simple interpolation - angular does this out of the box with two way data binding, for example, take the following:
<html ng-app="ExampleApp">
<body ng-controller="ExampleController as vm">
<div>Hello {{vm.name}}</div>
</body>
</html>
You could have a script like this:
angular.module('ExampleApp', [])
.controller('ExampleController', function(){
this.name = "World";
})
Which would print out "Hello World".
This is really basic though - if you're asking this question you definitely read more about angular before you attempt to create an application.
I would recommend the course at thinkster.
AngularJS provides possibilities to create HTML templates, data binding, loops, filters, ajax and you can extend everything you want with directives, you can create components to shrink you templates to be even smaller and concise. Here you can find examples and also some documentation, AngularJS is very popular so it's easy to find resources.

Turn on angularjs on only specific DOM hierarchies?

I'd like to turn off angular interpolation from the top level of my site but re-enable it for individual elements.
I'm trying to add some angular functionality to a rather large legacy site, and it's not feasible to add ng-non-bindable everywhere that could possibly contain {{bindable}} brackets. This is especially important because the site may have {{unparseable:er9 >-14?%(% randomness}} within those brackets. (Angular throws a [$parse:syntax] error for that and stops parsing any of the rest of my page)
Ideally, I'd set up something like <html ng-app="MyApp" ng-non-bindable> on every page, and then have <div ng-controller="myController"> on the few places that actually use angular.
So far I haven't figured out a way to do this. I looked at changing the angular parser to ignore text nodes until it sees a controller, but that seems like overkill. I also tried adding ng-app only to the nodes I want the app to live on, but I then have to manually bootstrap each node with the app, and I think that causes me to have multiple copies of the app running simultaneously and any singletons I was hoping for would (e.g. for cacheing) would be instantiated multiple times (unless I'm wrong about this?)
Is there a way to put ng-app and ng-non-bindable on the top level <html> and then manually add the divs I care about to the app?
I've set up a plunkr with a simple example: http://plnkr.co/edit/antMrWmWnKXHcxklh9IY?p=preview
Michal Charemza's comment above led me to a working solution.
I wrote a terminal directive that compiles and attaches to the $rootScope each [ng-bindable] element in the (using jquery):
app.directive('defaultNonBindable', ['$compile', '$rootScope',
function($compile, $rootScope) {
return {
compile: function(scope, elm, attrs) {
var bindables = $('[ng-bindable]');
bindables.each( function() {
var el = angular.element(this),
compiled = $compile(el);
compiled($rootScope);
});
},
terminal: true,
}
}
]);
I then wrap each block that's angular-ified in an ng-bindable div:
<div ng-bindable>
<div ng-controller="MyController">
{{this_works}}
</div>
</div>
I've forked the original plunkr with an example of it working: http://plnkr.co/edit/2rWCy7dwJNqTShXKiLgG?p=preview
One possible solution would be to configure angular in a way, that it is not looking for curly braces, but your own special syntax for interpolating.
var myApp = angular.module('App', []);
myApp.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
myApp.controller("Ctrl", function($scope){
$scope.value="value";
});
<div>[[value]]</div>
Plunker
I did not test it and there might be some side effects to it, especially for third party code, but it could be a way for managing the transition phase
regards

Resources