what is the best way to include markdown in angular-meteor - angularjs

I would like to include markdown text as part of my template.
I am using angular-meteor and I see 2 alternatives:
install a package of angular such as angular-markdown-directive
include a file without the .ng.html postfix and use meteor's markdown like this: {{#markdown}}{{>innerPreview}}{{/markdown}}
Is there other alternatives? will it work? which one is better?

I have created package oshai:angular-marked in atmosphere from hypercube's package. you can search for it in atmosphere.

At one point I created my own directive using showdown, but then decided I wanted to get rid of it and just use what Meteor already came with.
First thing. I have an .html file I called meteorTemplates.html. I just place all of the meteor templates in here that I use. I only have 2 and they're small.
In any case. The template looks like this:
<template name="mdTemplate">
{{#markdown}}{{md}}{{/markdown}}
</template>
Inside my controller I have:
$scope.my.markdown = '#Markdown';
According to angular-meteor docs:
The meteor-include directive holds the Angular scope of the directive as the as Template.currentData of the Meteor template.
So, Template.currentData == $scope.
Then inside the template helper I'll use the Template.currentData() like $scope.
Template.mdTemplate.helpers({
md: function() {
return Template.currentData().getReactively('my.markdown');
}
});
My ng.html file will look like:
<div id="markdown-preview">
<meteor-include src="mdTemplate"></meteor-include>
</div>

Related

HTML and JAVASCRIPT Editor in Angularjs

I have an angularjs 1.5.8 application created using Jhipster.
For my website I want to make a HTML and JAVASCRIPT editor. Need to allow user to write HTML Code but JAVASCRIPT also.
Using this library I know I can achieve the follow.
https://github.com/incuna/angular-bind-html-compile
1: Bind HTML Code.
2: Bind Angular code if present in HTML
Eg: <h1>{{$scope.test}}</h1>
Would render correct value in the scope.
But what about something like this in the html
<script>
console.log($scope);
</script>
I get a $scope not defined error, somehow the $scope value is not available in the script tag.
If anyone curious that why I need to do this because we want to provide users of the application to create there own Angularjs Forms.
I solved using ng-include, here is the example source.
I wanted to do two things.
1: Make ng-include work from a scope variable which will contain html and javascript.
2: In the included string if I have a script tag I wanted it to render correct in the ng-include.
To achieve the #1 I did the following.
Used $templateCache service.
Sample code.
$templateCache.put('template-form', vm.html + vm.script);
For point #2
I made sure the script tag is structured in the following way.
<script>
(function() {
'use strict';
angular.module('myApp').controllerProvider.register('AppTemplateController',AppTemplateController);
AppTemplateController.$inject = ['$scope'];
function AppTemplateController($scope){
// WRITE YOUR CODE IN THIS CONTROLLER
// YOU CAN WRITE YOUR VARIABLES/FUNCTIONS HERE.
// MAKE SURE TO CALL THE method "vm.submitForm", to submit your form and pass the form object.
};
})();
</script>
This way you can inject a controller.
My requirement was very very specific to my projecct, I am not sure if others who did not face this issue even would understand what I am talking about. But for those who do face it, I hope you it helpful

Using AngularJS to replace the HTML of one div

Using jQuery, it's easy to replace the innerHtml of a single div, either with content from the elsewhere in the HTML, from a JavaScript var, or from an HTTP call.
How can I do that in AngularJS (without using jQuery)? For example, to keep a page the same, but only replace a side panel?
Try using ng-view / ui-router . More details :
https://docs.angularjs.org/api/ngRoute/directive/ngView
angular-ui/ui-router, how do I inject partial view using $stateProvider?
It seems the answer is: "Think twice if you need to do this." In Angular, the paradigm isn't to modify the HTML, but rather to bind the HTML. So, bind the div's src to a scope or controller var via ngInclude, and just change that var.

Best way to modify html before binding to it in AngularJS directive

I'm writing an AngularJS app that gets a list of posts from a server, and then uses an ngRepeat and a custom post directive to output all the posts.
Part of the post object is a blob of html, which I currently add to the directive by first doing an $sce.trustAsHtml(blob), and then using the ng-bind-html directive and passing the trusted html blob to it. It works fine, but now I want to modify the html before adding it to the output. For instance, I want to find all link tags and add a target="_blank" to it. I also want to remove any content editable attributes from any element. etc.
What is the best way of doing this? I was thinking of just loading it up in a document fragment and then recursively iterating through all of the children doing what I need to do. But I assume there is a better AngularJS way to do this?
EDIT:
here is a codepen with an example of what I have:
http://codepen.io/niltz/pen/neqlC?editors=101
You can create a filter and pipe (|) your content through it. Something like:
<p ng-bind="myblob | myCleanupFilter">
Your myCleanupFilter would look something like this (not tested):
angular.module('myApp').filter('myCleanupFilter', function () {
return function cleanup (content) {
content.replace('......') // write your cleanup logic here...
};
});
If you want to add attributes that are themselves directives, then the best place to add them is in the compile function in a custom directive.
If they are just plain old attributes, then there's nothing wrong with hooking into DOM ready in your run block, and adding your attributes with jquery.
var app = app.module('app',[]);
app.run(function ($rootScope){
$(document).ready(function()
$rootScope.$apply(function(){
$('a').attr('title','cool');
});
})
});
If you want add the attributes after the compile phase but before the linking phase in the angular life cycle then a good place to do it is in the controller function for a directive that's placed on the body element.
<body ng-controller="bodyCtrl">
</body>
app.controller('bodyCtrl', function($element){
$('a', $element).attr('title','cool');
});
During the compile phase angular will walk the DOM tree, matching elements to directives, and transforming the HTML along the way. During the link phase, directives will typically set up watch handlers to update the view when the model changes. By placing a directive on the body element, it ensures that all directives have been compiled, but the linking phase hasn't started yet.

Jade Mixins in AngularJS

Hi I would like to implement Jade templates in my AngularJS project, and have mixin in my template (reusable code).
However the problem that I am facing is that we cannot use Mixin with arguments. Am I doing it correctly or is there any alternative for the same in AngularJS that I am missing?
You can create an js object from your model and pass it as strings to the mixin like the following:
+avatarRow({name: '{{avatar.name}}', uuid: '{{avatar.uuid}}', verificationCode: '{{avatar.verificationCode}}', status: '{{avatar.status}}'})
Inside the mixin you can now access e.g. #{avatar.uuid}
I considder to automate this further, because this leads to a duplication of the models code which is not so nice yet. I will share my solution if I get one :)
I figured out that mixins cannot be used in Angular as the scope is to be defined. Hence now created element directive and passed in the template (which was meant to be written in Mixin) as the templateUrl in it.

Intercept Angular template loading for use with Meteor+Blade

Little brief: I'm using AngularJs with Meteor+Blade without using Meteor_angularjs package for meteor. Blade constructs the body of the page in the server then I manually bootstrap angular in the client.
Blade has template files available under Template['template_name'] so they can be easily rendered on the client. I would like to do something like:
div(ng-include='content.blade')
// HTML => <div ng-include='content.blade'></div>
and somehow make it work.
To keep compatibility and not creating new directives I thought it could be possible to intercept the XHR requests angular makes to static templates and add the condition
if(URI ends with '.blade') then
name <- strip '.blade' in URI
return Template[name]()
Which should return the compiled HTML for that template.
UPDATE:
Coincidentally I ran into $templateCache and now I think it's the way to go.
I created a 'ngMeteor' module that I'll use for meteor-angular integration.
angular.module 'ngMeteor',[], ->
throw 'Meteor object undefined.' unless Meteor? # Is it fine to put here?
angular.module('ngMeteor.blade',['ngMeteor']).
run ($templateCache) ->
$templateCache.put "#{name}.blade", render() for own name, render of Template
In my app:
angular.element(document).ready ->
angular.bootstrap document, ['app']
app = angular.module 'app', ['ngMeteor.blade'], ->
app.controller 'mainCtrl', ($scope,$templateCache) ->
$scope.content = $templateCache.get "content.blade" # Works!!
Blade(body.blade):
#main(ng-controller='mainCtrl') {{ content }}
Now it works, I can get the rendered template from the controller after injecting $templateCache and geting the template by its name but ng-include still won't work.
My previous update in the question was actually the correct answer, ngInclude didn't work for me because of div(ng-include="'content.blade'") ... yes, the inner quotes! its like the Nth time I have that problem.
In resume the answer is:
angular.module('blade').
run ($templateCache) ->
$templateCache.put "#{name}.blade", render() for own name, render of Template
Template is the meteor global variable where blade will store templates ready to be rendered, then with $templateCache I put the rendered templates with the corresponding names/ids, that way Angular can use them.
EDIT: Based on this question I created a meteor package ng-meteor for braceless angular development in meteor.

Resources