nextcloud-files icon indicating copy to clipboard operation
nextcloud-files copied to clipboard

fix!: Allow to inherit from `View` to create custom classes

Open susnux opened this issue 1 year ago • 7 comments

Use case: You want to scope logic and state into the view rather than somewhere in a module.

Problems: Currently there are two problem that prevent creating a child-class of view:

  1. The view class did not implement the methods as methods but getters, this forces also child classes to use getters leading to really ugly code.
  2. The constructor required getContents to be part of the ViewData, but for child classes this makes no sense, as you probably want to overwrite this with a member function instead. Fixed by checking if new View was called or a new subclass.

susnux avatar Sep 03 '24 22:09 susnux

Bundle Report

Changes will increase total bundle size by 1.45kB :arrow_up:

Bundle name Size Change
@nextcloud/files-esm 118.08kB 722 bytes :arrow_up:
@nextcloud/files-esm-cjs 119.47kB 724 bytes :arrow_up:

codecov[bot] avatar Sep 03 '24 22:09 codecov[bot]

This option is slightly breaking, but only for the files app as it need to check hasEmptyView before applying it as view.emptyView will now always be a function.

I think just extending View for custom views is more natural than just working with an data object (looses a bit of validation, but that is the risk of the implementor). But I am fine with any solution, and I have to admit the alternative in the PR below is simpler.


:information_source: See alternative PR here

susnux avatar Sep 03 '24 22:09 susnux

This option is slightly breaking, but only for the files app as it need to check hasEmptyView before applying it as view.emptyView will now always be a function.

Why not keep it as getter?

skjnldsv avatar Sep 04 '24 07:09 skjnldsv

Why not keep it as getter?

Because you can not overwrite it in a custom class, it always then has to be a getter not a method. Meaning this would be not be allowed:

class MyView extend View {

    public emptyView(div: HTMLDivElement) {
        // do something
    }
}

Instead you would need to do:

class MyView extend View {

    public get emptyView() {
        return this.handleEmptyView.bind(this)
    }

    private handleEmptyView(div: HTMLDivElement) {
        // ...
    }
}

susnux avatar Sep 04 '24 17:09 susnux

(Thats the reason I also offer the alternative: https://github.com/nextcloud-libraries/nextcloud-files/pull/1068 )

susnux avatar Sep 04 '24 17:09 susnux

Why would you need to overwrite it? you can already customize the emptyView function when you create the View instance?

skjnldsv avatar Sep 05 '24 15:09 skjnldsv

Why would you need to overwrite it?

Because e.g. I want to have a local scope, meaning the emptyView should not just be a loose function but bound to my class, so that I can access (private) class properties. Meaning to be able to store view related state (e.g. the Vue instance of the empty view) inside of the View class instead being forced to store in in module scope.

susnux avatar Sep 05 '24 16:09 susnux