2

I am trying to saving some value in the Web part properties. I know in Spfx you can save or update any value in webpart property like

this.properties.myProp = "newValue";

I am using angular with sharepoint framework and want to access to value of the webpart property in the angular app.js file

I can access webpart property in the render method using this.properties;

In my render method I have something like this.

this.domElement.innerHTML = `<div ng-include="'settings/core/test.html'"></div>`; 

this.initializePromise
.then(() =>{
  //bootstrap element
// further code

My application code is in app.js and I want to access and modify the webpart properties in that file.

I tried storing the value of webpart properties in a global variable and accessing it but for same multiple webparts it causes problem, because of global scope both webpart properties are assigned same value.

How can I pass the scope of my render method to the app.js file so webpart properties are accessible in that file or simply how can I access the webpart properties in the angular app?

2

One way to do this I've found is to pass the information using a custom event on the $rootScope.

In your web part, you get a reference to $injector and each time the web part re-renders (which is triggered by a change to one or more properties), you broadcast an event:

export default class ToDoWebPartWebPart extends 

BaseClientSideWebPart<IToDoWebPartWebPartProps> {
  private $injector: ng.auto.IInjectorService;

  public render(): void {
    if (this.renderedOnce === false) {
      // omitted for brevity
      this.$injector = angular.bootstrap(this.domElement, ['todoapp']);
    }

    this.$injector.get('$rootScope').$broadcast('configurationChanged', {
      sharePointApi: this.properties.sharePointApi,
      todoListName: this.properties.todoListName,
      hideFinishedTasks: this.properties.hideFinishedTasks
    });
  }
}

Then, in the AngularJS application you subscribe to the event on $rootScope:

export default class HomeController {
  constructor(private dataService: IDataService, private $window: ng.IWindowService, private $rootScope: ng.IRootScopeService) {
    const vm: HomeController = this;
    this.init(null, null);

    $rootScope.$on('configurationChanged', (event: ng.IAngularEvent, args: { sharePointApi: string; todoListName: string; hideFinishedTasks: boolean }): void => {
      vm.init(args.sharePointApi, args.todoListName, args.hideFinishedTasks);
    });
  }
}

If you wanted to push changes to properties from the AngularJS application to the web part, you'd use the same approach but reversed: you'd broadcast the even in the AngularJS application and subscribe to it in the web part.

More info: https://blog.mastykarz.nl/building-sharepoint-framework-client-side-web-parts-angular/#passingwebpartsconfigurationintoangular

Hope this helps.

  • Thank you so much for your answer. I was able to get the same idea from this repository github.com/SharePoint/sp-dev-docs/blob/master/docs/spfx/… – Student Mar 27 '18 at 16:45
  • It was working perfectly on the workbench but on SharePoint online the webpart properties are losing the values when I refresh the page and are resetting to default. – Student Apr 4 '18 at 20:24
  • Are you testing it on a modern or a classic page? – Waldek Mastykarz - MVP Apr 6 '18 at 6:42
  • I am testing it in the Modern page. It is in read mode so webpart properties is not persisting the changes(as you mentioned in other comment). what about the onBeforeSerialize() method. will it also save only in edit mode? – Student Apr 6 '18 at 8:09
  • Web part data is persisted in page properties, so if the page is not being edited, these properties are not going to be updated. – Waldek Mastykarz - MVP Apr 9 '18 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.