Closed frankspin89 closed 6 years ago
Hi @frankspin89,
I'd also love to hear from anyone who has integrated ContentTools with Angular2. I know lots of devs use Angular2 but unfortunately I don't myself and I'm not in contact with anyone who does (admittedly it's a small circle but most of the devs I speak to frequently are React or Vue based).
Sorry I can't personally be of any help @frankspin89 - I'll send out a tweet also asking the same question.
@anthonyjb Thanks for your replay. I'm now trying to implement it myself. I have the basics working now.
ContentToolsComponent
const ContentToolsLib = require('./contenttools.js');
import { NgModule, EventEmitter, AfterViewInit, Component, Output, Input, OnDestroy } from '@angular/core';
@Component({
selector: 'app-content-tools',
template: '<div class="content-tools"><ng-content></ng-content></div>',
})
@NgModule({
declarations: [ContentToolsComponent],
exports: [ContentToolsComponent]
})
export class ContentToolsComponent implements AfterViewInit, OnDestroy {
@Output() onSave = new EventEmitter<Object>();
editor = ContentToolsLib.EditorApp.get();
ngAfterViewInit() {
this.editor.init('*[data-editable]', 'data-name');
this.editor.addEventListener('saved', ev => {
const regions = ev.detail().regions;
this.onSave.emit(regions);
});
}
ngOnDestroy() {
this.editor.destroy();
}
}
And then use the component like this
<app-content-tools (onSave)="onSave($event)">
<div data-editable data-name="heading" [innerHTML]="post.heading">
</div>
<div data-editable data-name="content" [innerHTML]="post.content">
</div>
</app-content-tools>
Far from pretty at the moment. Keep updating this thread if I made some progress. All help is welcome to implement this Awesome library in to Angular 2+
@anthonyjb question: I'm trying to implement auto saving.
The problem that i'm facing is that angular is replacing the dom when the content is updated. That is resulting in the fact that you can't edit the updated section/region.
Is there a method that I can call after a successful save to reactive the editor in the updated section/region? Found: this.editor.start();
but that isn't working for me
@frankspin89 so if you perform a passive save (e.g editor.save(true)
) then CT wont update the DOM it will only collected the modified data, does that help?
@anthonyjb I don't think that it makes any difference. I'm using a realtime database and want to create a option to collaborate on a single page in realtime. So after x seconds I save the data from ContentTools to the database. A listener is then updating the dom with the fresh data.
The saving part is working correctly at the moment. Only updating the dom with the fresh data is problematic.
To make the updated region editable again, I have to manually close the editor and start the editor again. So i'm looking for a function to call after I updated the dom with the fresh data.
@frankspin89 ok that makes sense now, I think you're looking for editor.syncRegions('*[data-editable]', true)
.
This will resync the the editable regions with the DOM and if the editor is running it will do it live. We have to send the '*[data-editable]' argument to force the editor to pick up the replaced DOM elements, and the second argument is to let the editor know it's restoring e (not initialising) so it doesn't change the last modified date against the region (which I think here is what you want).
Let me know how you get on.
@anthonyjb I think that .syncRegions is the right function. But I'm not sure why it's not working for me.
ContentToolsComponent
const ContentToolsLib = require('./contenttools.js');
import {
NgModule, ViewChild, EventEmitter, AfterViewInit,
ElementRef, Component, Output, Input, OnDestroy, OnChanges
} from '@angular/core';
import { Observable } from 'rxjs/Observable';
@Component({
selector: 'app-content-tools',
template: '<div #contenttools class="content-tools"><ng-content></ng-content></div>',
})
@NgModule({
declarations: [ContentToolsComponent],
exports: [ContentToolsComponent]
})
export class ContentToolsComponent implements AfterViewInit, OnDestroy, OnChanges {
@Output() onSave = new EventEmitter<Object>();
@Input() editorState;
@ViewChild('contenttools') element: ElementRef;
editor = ContentToolsLib.EditorApp.get();
ngAfterViewInit() {
this.editor.init('*[data-editable]', 'data-name');
const that = this;
this.editor.addEventListener('saved', function (ev) {
const regions = ev.detail().regions;
if (Object.keys(regions).length === 0) {
return;
}
that.onSave.emit(regions);
});
this.editor.addEventListener('start', function (ev) {
const that = this;
function autoSave() {
that.save(true);
};
this.autoSaveTimer = setInterval(autoSave, 5 * 1000);
});
}
ngOnChanges() {
if (this.editorState) {
const state = this.editor.getState();
const domRegions = this.editor.domRegions();
console.log('state', state);
console.log('doms', domRegions);
this.editor.syncRegions('*[data-editable]', true);
this.editorState = false;
}
}
ngOnDestroy() {
this.editor.destroy();
}
}
Component that uses ContentToolsComponent
import { Component, OnInit } from '@angular/core';
import { ClientService } from 'app/shared';
import { ContentToolsComponent } from '../shared/contenttools/contenttools';
import { ProposalService } from '../shared/services/proposal.service';
@Component({
selector: 'app-proposals',
templateUrl: './proposals.component.html',
})
export class ProposalsComponent implements OnInit {
private post: Object;
private editorState = false;
constructor(
private proposalService: ProposalService
) { }
ngOnInit() {
this.proposalService.loadProposal().subscribe(
proposal => this.post = proposal
);
}
onSave(regions) {
this.post = Object.assign({}, this.post, regions);
this.proposalService.updateProposal(this.post).take(1).subscribe(data => this.editorState = true);
}
}
Template
<h1>Proposals</h1>
<app-content-tools (onSave)="onSave($event)" [editorState]="editorState" *ngIf="post">
<div data-editable data-name="heading" [innerHTML]="post.heading">
</div>
<div data-editable data-name="content" [innerHTML]="post.content">
</div>
</app-content-tools>
DOM before update
<app-content-tools _ngcontent-fkp-20="" ng-reflect-editor-state="true">
<div class="content-tools">
<div _ngcontent-fkp-20="" data-editable="" data-name="content" ng-reflect-inner-h-t-m-l="<h2>&#10; The content of the page&#10;</h2>&#10;<p>&#10; &#10;</p>">
<h2 class="ce-element ce-element--type-text ce-element--focused" contenteditable="">The content of the page</h2>
<p class="ce-element--empty ce-element ce-element--type-text"></p>
</div>
</div>
</app-content-tools>
DOM after update
<app-content-tools _ngcontent-fkp-20="" ng-reflect-editor-state="true">
<div class="content-tools">
<div _ngcontent-fkp-20="" data-editable="" data-name="content" ng-reflect-inner-h-t-m-l="<h2>&#10; The new content of the page&#10;</h2>&#10;<p>&#10; &#10;</p>">
<h2>The new content of the page</h2>
<p></p>
</div>
</div>
</app-content-tools>
Hi @frankspin89 ok so I think I perhaps we need to try a different approach, I hadn't fully comprehended what was going on before, so instead of syncRegions
lets define a new function which will bring the inner content of each region in line...
function updateRegions() {
var editor = ContentToolsLib.EditorApp.get();
// For each editable region
for (var name in editor.regions()) {
var region = editor.regions()[name];
// Set the content the editable content for the region to the inner contents
//
// NOTE: This isn't safe to do if the content of the region is still editable as
// you get editable > editable content - not a good thing.
region.setContent(region.domElement());
}
}
If you know the region updated from your query with the remote server you could just look up that region and and set it's inner contents, which would be far more efficient than updating all of the regions (if there are multiple). You can also just send setContent
a HTML string which might be preferable.
Let me know how you get on - sorry for the slightly delayed reply.
Hi @frankspin89 , @al-on-github , Is there any publicly available result of this effort? I would love to use ContentTools with Angular 6 too.
ping @frankspin89 @al-on-github @ZsZs any news on this?
ping @frankspin89 @al-on-github @ZsZs any news on this?
+1
Is there any reference or guide available to implement ContentTools with Angular (2+)?
Found some guides to implement ContentTools with AngularJs, only is Angular (2+) so different then AngularJs that it's not workable.
Love to hear what my options are.